create-turbo-mono 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/.claude/settings.local.json +4 -10
  2. package/.dockerignore +48 -0
  3. package/.env.example +39 -0
  4. package/.github/workflows/ci-cd-staging.yml +135 -0
  5. package/.github/workflows/ci-cd.yml +130 -0
  6. package/Dockerfile +125 -0
  7. package/README.md +88 -135
  8. package/apps/backend/api/.env.example +2 -0
  9. package/apps/backend/api/.eslintrc.js +25 -0
  10. package/apps/backend/api/.prettierrc +4 -0
  11. package/apps/backend/api/README.md +45 -0
  12. package/apps/backend/api/nest-cli.json +8 -0
  13. package/apps/backend/api/package.json +80 -0
  14. package/apps/backend/api/src/app.controller.spec.ts +22 -0
  15. package/apps/backend/api/src/app.controller.ts +12 -0
  16. package/apps/backend/api/src/app.module.ts +15 -0
  17. package/apps/backend/api/src/app.service.ts +8 -0
  18. package/apps/backend/api/src/main.ts +22 -0
  19. package/apps/backend/api/test/app.e2e-spec.ts +24 -0
  20. package/apps/backend/api/test/jest-e2e.json +13 -0
  21. package/apps/backend/api/tsconfig.build.json +9 -0
  22. package/apps/backend/api/tsconfig.json +22 -0
  23. package/apps/frontend/web/.env.local.example +1 -0
  24. package/apps/frontend/web/.eslintrc.json +3 -0
  25. package/apps/frontend/web/README.md +34 -0
  26. package/apps/frontend/web/next.config.js +7 -0
  27. package/apps/frontend/web/package.json +29 -0
  28. package/apps/frontend/web/pages/_app.tsx +6 -0
  29. package/apps/frontend/web/pages/_document.tsx +13 -0
  30. package/apps/frontend/web/pages/api/hello.ts +12 -0
  31. package/apps/frontend/web/pages/index.tsx +113 -0
  32. package/apps/frontend/web/public/next.svg +1 -0
  33. package/apps/frontend/web/public/vercel.svg +1 -0
  34. package/apps/frontend/web/styles/Home.module.css +56 -0
  35. package/apps/frontend/web/styles/globals.css +44 -0
  36. package/apps/frontend/web/tsconfig.json +33 -0
  37. package/dist/index.js +0 -0
  38. package/docker-compose.dev.yml +99 -0
  39. package/docker-compose.local.yml +50 -0
  40. package/docker-compose.prod.yml +93 -0
  41. package/docs/ENVIRONMENT.md +52 -0
  42. package/package.json +1 -1
  43. package/packages/database/.env.example +1 -0
  44. package/packages/database/README.md +28 -0
  45. package/packages/database/package.json +24 -0
  46. package/packages/database/prisma/schema.prisma +34 -0
  47. package/packages/database/src/index.ts +18 -0
  48. package/packages/database/tsconfig.json +14 -0
  49. package/packages/shared-backend/README.md +14 -0
  50. package/packages/shared-backend/package.json +20 -0
  51. package/packages/shared-backend/src/index.ts +2 -0
  52. package/packages/shared-backend/src/types/index.ts +12 -0
  53. package/packages/shared-backend/src/utils/index.ts +2 -0
  54. package/packages/shared-backend/src/utils/logger.ts +25 -0
  55. package/packages/shared-backend/src/utils/response.ts +22 -0
  56. package/packages/shared-backend/tsconfig.json +14 -0
  57. package/packages/shared-common/README.md +13 -0
  58. package/packages/shared-common/package.json +16 -0
  59. package/packages/shared-common/src/constants/index.ts +4 -0
  60. package/packages/shared-common/src/index.ts +3 -0
  61. package/packages/shared-common/src/types/index.ts +9 -0
  62. package/packages/shared-common/src/utils/formatting.ts +18 -0
  63. package/packages/shared-common/src/utils/index.ts +2 -0
  64. package/packages/shared-common/src/utils/validation.ts +21 -0
  65. package/packages/shared-common/tsconfig.json +14 -0
  66. package/packages/shared-frontend/README.md +15 -0
  67. package/packages/shared-frontend/package.json +28 -0
  68. package/packages/shared-frontend/src/components/Button.tsx +37 -0
  69. package/packages/shared-frontend/src/components/index.ts +1 -0
  70. package/packages/shared-frontend/src/hooks/index.ts +1 -0
  71. package/packages/shared-frontend/src/hooks/useLocalStorage.ts +33 -0
  72. package/packages/shared-frontend/src/index.ts +3 -0
  73. package/packages/shared-frontend/src/utils/cn.ts +3 -0
  74. package/packages/shared-frontend/src/utils/index.ts +1 -0
  75. package/packages/shared-frontend/tsconfig.json +14 -0
  76. package/packages/tsconfig/base.json +23 -0
  77. package/packages/tsconfig/nestjs.json +17 -0
  78. package/packages/tsconfig/nextjs.json +28 -0
  79. package/packages/tsconfig/package.json +5 -0
  80. package/packages/tsconfig/react-library.json +16 -0
  81. package/scripts/deploy.sh +67 -0
  82. package/scripts/rollback.sh +30 -0
  83. package/turbo.json +39 -0
@@ -1,16 +1,10 @@
1
1
  {
2
2
  "permissions": {
3
3
  "allow": [
4
+ "Bash(npm view:*)",
5
+ "Bash(python3:*)",
4
6
  "Bash(npm install:*)",
5
- "Bash(npm run build:*)",
6
- "Bash(npx turbo:*)",
7
- "Bash(npx prisma generate:*)",
8
- "Bash(npx tsx:*)",
9
- "Bash(pnpm build:*)",
10
- "Bash(pnpm install:*)",
11
- "Bash(docker build:*)"
12
- ],
13
- "deny": [],
14
- "ask": []
7
+ "Bash(npm run build:*)"
8
+ ]
15
9
  }
16
10
  }
package/.dockerignore ADDED
@@ -0,0 +1,48 @@
1
+ # Dependencies
2
+ node_modules
3
+ npm-debug.log*
4
+ yarn-debug.log*
5
+ yarn-error.log*
6
+ pnpm-debug.log*
7
+
8
+ # Build outputs
9
+ dist
10
+ .next
11
+ out
12
+ build
13
+ *.tsbuildinfo
14
+
15
+ # Testing
16
+ coverage
17
+ .nyc_output
18
+
19
+ # Environment
20
+ .env
21
+ .env.*
22
+ !.env.example
23
+
24
+ # Misc
25
+ .DS_Store
26
+ *.pem
27
+ .vscode
28
+ .idea
29
+
30
+ # Git
31
+ .git
32
+ .gitignore
33
+
34
+ # Docker
35
+ Dockerfile*
36
+ docker-compose*.yml
37
+ .dockerignore
38
+
39
+ # Documentation
40
+ *.md
41
+ !README.md
42
+
43
+ # CI/CD
44
+ .github
45
+ .gitlab-ci.yml
46
+
47
+ # Turborepo
48
+ .turbo
package/.env.example ADDED
@@ -0,0 +1,39 @@
1
+ # Project Configuration
2
+ PROJECT_NAME=my-app
3
+ GITHUB_REPOSITORY=your-org/your-repo
4
+
5
+ # Database Configuration
6
+ DATABASE_USER=postgres
7
+ DATABASE_PASSWORD=postgres
8
+ DATABASE_NAME=app_db
9
+ DATABASE_PORT=5432
10
+ DATABASE_URL=postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@postgres:5432/${DATABASE_NAME}
11
+
12
+ # Redis Configuration
13
+ REDIS_URL=redis://redis:6379
14
+ REDIS_PORT=6379
15
+
16
+ # Application Ports
17
+ # Backend services will use 4000+
18
+ # Frontend services will use 3000+
19
+
20
+ # Production Deployment
21
+ RELEASE_TAG=latest
22
+
23
+ # API Configuration
24
+ NEXT_PUBLIC_API_URL=http://localhost:4000
25
+
26
+ # Email Notifications (for CI/CD)
27
+ # SMTP_SERVER=smtp.gmail.com
28
+ # SMTP_PORT=587
29
+ # SMTP_SECURE=true
30
+ # SMTP_USERNAME=your-email@gmail.com
31
+ # SMTP_PASSWORD=your-app-password
32
+ # DEPLOY_NOTIFY_TO=team@example.com
33
+
34
+ # Deployment Server (for CI/CD)
35
+ # SSH_HOST=your-server.com
36
+ # SSH_USER=deploy
37
+ # SSH_KEY=<your-private-key>
38
+ # SSH_PORT=22
39
+ # DEPLOY_PATH=/home/deploy/app
@@ -0,0 +1,135 @@
1
+ name: CI/CD (staging)
2
+
3
+ on:
4
+ push:
5
+ branches: ['develop', 'staging']
6
+ pull_request:
7
+ branches: ['develop', 'staging']
8
+
9
+ env:
10
+ REGISTRY: ghcr.io
11
+ IMAGE_NAME: ${{ github.repository }}
12
+
13
+ jobs:
14
+ build-and-push:
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: read
18
+ packages: write
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ service: ['api', 'web']
23
+
24
+ steps:
25
+ - name: 📥 Checkout repository
26
+ uses: actions/checkout@v4
27
+
28
+ - name: 🐳 Set up QEMU
29
+ uses: docker/setup-qemu-action@v3
30
+
31
+ - name: 🏗️ Set up Docker Buildx
32
+ uses: docker/setup-buildx-action@v3
33
+
34
+ - name: 🔐 Login to GitHub Container Registry
35
+ uses: docker/login-action@v3
36
+ with:
37
+ registry: ${{ env.REGISTRY }}
38
+ username: ${{ github.actor }}
39
+ password: ${{ secrets.GITHUB_TOKEN }}
40
+
41
+ - name: 🏷️ Extract metadata
42
+ id: meta
43
+ uses: docker/metadata-action@v5
44
+ with:
45
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.service }}
46
+ tags: |
47
+ type=ref,event=branch
48
+ type=ref,event=pr
49
+ type=sha,prefix={{branch}}-
50
+ type=raw,value=staging,enable={{is_default_branch}}
51
+
52
+ - name: 🔨 Build and push Docker image
53
+ uses: docker/build-push-action@v5
54
+ with:
55
+ context: .
56
+ file: Dockerfile
57
+ target: ${{ matrix.service }}-production
58
+ push: ${{ github.event_name != 'pull_request' }}
59
+ tags: ${{ steps.meta.outputs.tags }}
60
+ labels: ${{ steps.meta.outputs.labels }}
61
+ cache-from: type=gha
62
+ cache-to: type=gha,mode=max
63
+ build-args: |
64
+ NEXT_PUBLIC_API_URL=${{ secrets.STAGING_API_URL }}
65
+
66
+ deploy-staging:
67
+ needs: [build-and-push]
68
+ runs-on: ubuntu-latest
69
+ if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
70
+
71
+ steps:
72
+ - name: 📥 Checkout repository
73
+ uses: actions/checkout@v4
74
+
75
+ - name: 🏷️ Compute deployment tag
76
+ id: tag
77
+ run: echo "TAG=develop" >> $GITHUB_OUTPUT
78
+
79
+ - name: 🚀 Deploy to staging server
80
+ uses: appleboy/ssh-action@v1.0.0
81
+ env:
82
+ TAG: ${{ steps.tag.outputs.TAG }}
83
+ APP_DIR: ${{ secrets.STAGING_DEPLOY_PATH }}
84
+ GHCR_TOKEN: ${{ secrets.GHCR_PAT }}
85
+ GHCR_USER: ${{ github.actor }}
86
+ with:
87
+ host: ${{ secrets.SSH_HOST }}
88
+ username: ${{ secrets.SSH_USER }}
89
+ key: ${{ secrets.SSH_KEY }}
90
+ port: ${{ secrets.SSH_PORT || 22 }}
91
+ script_stop: true
92
+ envs: TAG,APP_DIR,GHCR_TOKEN,GHCR_USER
93
+ script: |
94
+ set -euo pipefail
95
+ echo "📦 Deploying STAGING tag: ${TAG}"
96
+ echo "📁 APP_DIR: ${APP_DIR}"
97
+ echo "${GHCR_TOKEN}" | docker login ghcr.io -u "${GHCR_USER}" --password-stdin
98
+ cd "${APP_DIR}"
99
+ chmod +x scripts/deploy.sh
100
+ ./scripts/deploy.sh "${TAG}"
101
+
102
+ - name: ✉️ Send staging deployment notification
103
+ if: always()
104
+ uses: dawidd6/action-send-mail@v3
105
+ with:
106
+ server_address: ${{ secrets.SMTP_SERVER }}
107
+ server_port: ${{ secrets.SMTP_PORT }}
108
+ secure: ${{ secrets.SMTP_SECURE }}
109
+ username: ${{ secrets.SMTP_USERNAME }}
110
+ password: ${{ secrets.SMTP_PASSWORD }}
111
+ subject: 'STAGING Deployment #${{ github.run_number }} - ${{ job.status }}'
112
+ from: 'CI/CD <${{ secrets.SMTP_USERNAME }}>'
113
+ to: ${{ secrets.DEPLOY_NOTIFY_TO }}
114
+ html_body: |
115
+ <div style="font-family:'Segoe UI',Helvetica,Arial,sans-serif;background:#f6f8fa;padding:20px;">
116
+ <div style="max-width:600px;margin:0 auto;background:#fff;border-radius:10px;box-shadow:0 2px 6px rgba(0,0,0,0.1);overflow:hidden;">
117
+ <div style="background:linear-gradient(90deg,#f59e0b,#d97706);padding:16px 24px;color:#fff;">
118
+ <h2 style="margin:0;font-size:20px;">🚀 STAGING Deployment</h2>
119
+ </div>
120
+ <div style="padding:24px;">
121
+ <table style="width:100%;border-collapse:collapse;margin-top:8px;">
122
+ <tr><td style="padding:6px 0;color:#555;font-weight:600;">Repository</td><td>${{ github.repository }}</td></tr>
123
+ <tr style="background:#f9fafb;"><td style="padding:6px 0;color:#555;font-weight:600;">Branch</td><td>${{ github.ref_name }}</td></tr>
124
+ <tr><td style="padding:6px 0;color:#555;font-weight:600;">Commit</td><td><code>${{ github.sha }}</code></td></tr>
125
+ <tr style="background:#f9fafb;"><td style="padding:6px 0;color:#555;font-weight:600;">Tag</td><td>${{ steps.tag.outputs.TAG }}</td></tr>
126
+ <tr><td style="padding:6px 0;color:#555;font-weight:600;">Status</td>
127
+ <td><span style="padding:3px 8px;border-radius:6px;background:#f59e0b;color:#fff;font-size:12px;">${{ job.status }}</span></td></tr>
128
+ </table>
129
+ <p style="margin:16px 0 8px;color:#444;">View full deployment logs:</p>
130
+ <a href="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
131
+ style="display:inline-block;background:#f59e0b;color:#fff;padding:10px 16px;border-radius:6px;text-decoration:none;font-weight:500;">🔍 View Details</a>
132
+ <p style="margin-top:20px;font-size:12px;color:#888;">— DevOps Pipeline (STAGING)</p>
133
+ </div>
134
+ </div>
135
+ </div>
@@ -0,0 +1,130 @@
1
+ name: CI/CD (main)
2
+
3
+ on:
4
+ push:
5
+ branches: ['main']
6
+ pull_request:
7
+ branches: ['main']
8
+
9
+ env:
10
+ REGISTRY: ghcr.io
11
+ IMAGE_NAME: ${{ github.repository }}
12
+
13
+ jobs:
14
+ build-and-push:
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: read
18
+ packages: write
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ service: ['api', 'web']
23
+
24
+ steps:
25
+ - name: 📥 Checkout repository
26
+ uses: actions/checkout@v4
27
+
28
+ - name: 🐳 Set up QEMU
29
+ uses: docker/setup-qemu-action@v3
30
+
31
+ - name: 🏗️ Set up Docker Buildx
32
+ uses: docker/setup-buildx-action@v3
33
+
34
+ - name: 🔐 Login to GitHub Container Registry
35
+ uses: docker/login-action@v3
36
+ with:
37
+ registry: ${{ env.REGISTRY }}
38
+ username: ${{ github.actor }}
39
+ password: ${{ secrets.GITHUB_TOKEN }}
40
+
41
+ - name: 🏷️ Extract metadata
42
+ id: meta
43
+ uses: docker/metadata-action@v5
44
+ with:
45
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.service }}
46
+ tags: |
47
+ type=ref,event=branch
48
+ type=ref,event=pr
49
+ type=sha,prefix={{branch}}-
50
+ type=raw,value=latest,enable={{is_default_branch}}
51
+
52
+ - name: 🔨 Build and push Docker image
53
+ uses: docker/build-push-action@v5
54
+ with:
55
+ context: .
56
+ file: Dockerfile
57
+ target: ${{ matrix.service }}-production
58
+ push: ${{ github.event_name != 'pull_request' }}
59
+ tags: ${{ steps.meta.outputs.tags }}
60
+ labels: ${{ steps.meta.outputs.labels }}
61
+ cache-from: type=gha
62
+ cache-to: type=gha,mode=max
63
+
64
+ deploy:
65
+ needs: [build-and-push]
66
+ runs-on: ubuntu-latest
67
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
68
+
69
+ steps:
70
+ - name: 📥 Checkout repository
71
+ uses: actions/checkout@v4
72
+
73
+ - name: 🏷️ Compute deployment tag
74
+ id: tag
75
+ run: echo "TAG=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
76
+
77
+ - name: 🚀 Deploy to server
78
+ uses: appleboy/ssh-action@v1.0.0
79
+ env:
80
+ TAG: ${{ steps.tag.outputs.TAG }}
81
+ APP_DIR: ${{ secrets.DEPLOY_PATH }}
82
+ with:
83
+ host: ${{ secrets.SSH_HOST }}
84
+ username: ${{ secrets.SSH_USER }}
85
+ key: ${{ secrets.SSH_KEY }}
86
+ port: ${{ secrets.SSH_PORT || 22 }}
87
+ script_stop: true
88
+ envs: TAG,APP_DIR
89
+ script: |
90
+ set -euo pipefail
91
+ echo "📦 Deploying tag: ${TAG}"
92
+ echo "📁 APP_DIR: ${APP_DIR}"
93
+ cd "${APP_DIR}"
94
+ chmod +x scripts/deploy.sh
95
+ ./scripts/deploy.sh "${TAG}"
96
+
97
+ - name: ✉️ Send deployment notification
98
+ if: always()
99
+ uses: dawidd6/action-send-mail@v3
100
+ with:
101
+ server_address: ${{ secrets.SMTP_SERVER }}
102
+ server_port: ${{ secrets.SMTP_PORT }}
103
+ secure: ${{ secrets.SMTP_SECURE }}
104
+ username: ${{ secrets.SMTP_USERNAME }}
105
+ password: ${{ secrets.SMTP_PASSWORD }}
106
+ subject: 'Deployment #${{ github.run_number }} - ${{ job.status }}'
107
+ from: 'CI/CD <${{ secrets.SMTP_USERNAME }}>'
108
+ to: ${{ secrets.DEPLOY_NOTIFY_TO }}
109
+ html_body: |
110
+ <div style="font-family:'Segoe UI',Helvetica,Arial,sans-serif;background:#f6f8fa;padding:20px;">
111
+ <div style="max-width:600px;margin:0 auto;background:#fff;border-radius:10px;box-shadow:0 2px 6px rgba(0,0,0,0.1);overflow:hidden;">
112
+ <div style="background:linear-gradient(90deg,#2563eb,#1e3a8a);padding:16px 24px;color:#fff;">
113
+ <h2 style="margin:0;font-size:20px;">🚀 Deployment Notification</h2>
114
+ </div>
115
+ <div style="padding:24px;">
116
+ <table style="width:100%;border-collapse:collapse;margin-top:8px;">
117
+ <tr><td style="padding:6px 0;color:#555;font-weight:600;">Repository</td><td>${{ github.repository }}</td></tr>
118
+ <tr style="background:#f9fafb;"><td style="padding:6px 0;color:#555;font-weight:600;">Branch</td><td>${{ github.ref_name }}</td></tr>
119
+ <tr><td style="padding:6px 0;color:#555;font-weight:600;">Commit</td><td><code>${{ github.sha }}</code></td></tr>
120
+ <tr style="background:#f9fafb;"><td style="padding:6px 0;color:#555;font-weight:600;">Tag</td><td>${{ steps.tag.outputs.TAG }}</td></tr>
121
+ <tr><td style="padding:6px 0;color:#555;font-weight:600;">Status</td>
122
+ <td><span style="padding:3px 8px;border-radius:6px;background:#2563eb;color:#fff;font-size:12px;">${{ job.status }}</span></td></tr>
123
+ </table>
124
+ <p style="margin:16px 0 8px;color:#444;">View full deployment logs:</p>
125
+ <a href="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
126
+ style="display:inline-block;background:#2563eb;color:#fff;padding:10px 16px;border-radius:6px;text-decoration:none;font-weight:500;">🔍 View Details</a>
127
+ <p style="margin-top:20px;font-size:12px;color:#888;">— DevOps Pipeline</p>
128
+ </div>
129
+ </div>
130
+ </div>
package/Dockerfile ADDED
@@ -0,0 +1,125 @@
1
+ # syntax=docker/dockerfile:1
2
+
3
+ # ============================================
4
+ # Global Build Arguments
5
+ # ============================================
6
+ ARG NODE_VERSION=20
7
+ ARG DATABASE_URL
8
+
9
+ # ============================================
10
+ # Base Stage – Node + pnpm + Workspace setup
11
+ # ============================================
12
+ FROM node:${NODE_VERSION}-slim AS base
13
+
14
+ # Install pnpm
15
+ RUN corepack enable && corepack prepare pnpm@latest --activate
16
+
17
+ # Install essentials including OpenSSL
18
+ RUN apt-get update && \
19
+ apt-get install -y curl bash postgresql-client openssl ca-certificates && \
20
+ rm -rf /var/lib/apt/lists/*
21
+
22
+ WORKDIR /app
23
+
24
+ # Workspace files
25
+ COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
26
+ COPY turbo.json ./
27
+ COPY packages/ packages/
28
+
29
+ # App-level package.json
30
+ COPY apps/backend/api/package.json apps/backend/api/
31
+ COPY apps/frontend/web/package.json apps/frontend/web/
32
+
33
+ # ============================================
34
+ # Dependencies Stage
35
+ # ============================================
36
+ FROM base AS dependencies
37
+
38
+ RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
39
+ pnpm install --frozen-lockfile
40
+
41
+ # ============================================
42
+ # Shared Libraries + Prisma Clients
43
+ # ============================================
44
+ FROM dependencies AS shared-libs
45
+
46
+ ARG DATABASE_URL
47
+ ENV DATABASE_URL=${DATABASE_URL}
48
+
49
+ # Prisma schema
50
+ COPY packages/database/prisma/ packages/database/prisma/
51
+
52
+ # Copy database source code
53
+ COPY packages/database/src/ packages/database/src/
54
+ COPY packages/database/tsconfig.json packages/database/tsconfig.json
55
+
56
+ # Generate Prisma client AND build the database package
57
+ RUN echo "🧩 Building database package..." && \
58
+ cd packages/database && \
59
+ pnpm prisma generate && \
60
+ pnpm run build
61
+
62
+ # Build shared packages
63
+ RUN --mount=type=cache,id=turbo,target=/app/node_modules/.cache \
64
+ pnpm turbo run build --filter="@repo/shared-*"
65
+
66
+ # ============================================
67
+ # Common Build Base
68
+ # ============================================
69
+ FROM shared-libs AS build-base
70
+
71
+ # Source
72
+ COPY apps/ apps/
73
+
74
+ ENV NODE_ENV=production
75
+ ENV NEXT_TELEMETRY_DISABLED=1
76
+
77
+ # ============================================
78
+ # API Production
79
+ # ============================================
80
+ FROM build-base AS api-production
81
+ WORKDIR /app/apps/backend/api
82
+
83
+ ENV NODE_OPTIONS="--max-old-space-size=4096"
84
+
85
+ RUN --mount=type=cache,id=nest,target=/app/node_modules/.cache \
86
+ echo "📦 Building api..." && \
87
+ pnpm run build
88
+
89
+ ENV NODE_OPTIONS="--max-old-space-size=2048"
90
+
91
+ EXPOSE 3000
92
+
93
+ # Start API directly (migrations handled separately)
94
+ CMD ["sh", "-c", "cd /app/apps/backend/api && pnpm run start:prod"]
95
+
96
+ # ============================================
97
+ # API Development
98
+ # ============================================
99
+ FROM shared-libs AS api-development
100
+ WORKDIR /app/apps/backend/api
101
+ ENV NODE_ENV=development
102
+
103
+ EXPOSE 3000
104
+ CMD ["sh", "-c", "cd /app/apps/backend/api && pnpm run dev"]
105
+
106
+ # ============================================
107
+ # WEB Production
108
+ # ============================================
109
+ FROM build-base AS web-production
110
+ WORKDIR /app/apps/frontend/web
111
+
112
+ # Accept API URL as build argument
113
+ ARG NEXT_PUBLIC_API_URL=http://localhost:3000
114
+ ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
115
+ ENV NODE_OPTIONS="--max-old-space-size=4096"
116
+ ENV NEXT_TELEMETRY_DISABLED=1
117
+
118
+ RUN --mount=type=cache,id=next,target=/app/node_modules/.cache \
119
+ echo "🌐 Building web with API URL: ${NEXT_PUBLIC_API_URL}" && \
120
+ pnpm next build
121
+
122
+ ENV NODE_OPTIONS="--max-old-space-size=2048"
123
+
124
+ EXPOSE 3000
125
+ CMD ["pnpm", "run", "start"]