Browse Source

Optimize Docker multi-stage build and fix production compilation

- Streamline Dockerfile with optimized multi-stage build
- Eliminate duplicate system dependencies and package installations
- Fix production builds to properly compile Next.js, NestJS, and CLI apps
- Update service start script to run compiled code (node dist/main)
- Add turbo start task for orchestrating production services
- Update docker-compose.yml for production mode
- Improve build efficiency and reduce image size
Timothy Pomeroy 1 tháng trước cách đây
mục cha
commit
0583888407
5 tập tin đã thay đổi với 33 bổ sung55 xóa
  1. 21 49
      Dockerfile
  2. 1 0
      README.md
  3. 1 1
      apps/service/package.json
  4. 4 4
      docker-compose.yml
  5. 6 1
      turbo.json

+ 21 - 49
Dockerfile

@@ -1,5 +1,5 @@
-# Base stage with system dependencies
-FROM node:20 AS base
+# Base stage with system dependencies and pnpm
+FROM node:20-slim AS base
 
 # Install system dependencies including HandBrakeCLI, SQLite, and FFmpeg
 RUN apt-get update && apt-get install -y \
@@ -8,22 +8,18 @@ RUN apt-get update && apt-get install -y \
     ffmpeg \
     && rm -rf /var/lib/apt/lists/*
 
-# Install pnpm
+# Install pnpm globally
 RUN npm install -g pnpm
 
 WORKDIR /app
 
+# Dependencies stage - install all dependencies
+FROM base AS dependencies
+
 # Copy package files for dependency installation
 COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./
-COPY apps/web/package.json apps/web/
-COPY apps/service/package.json apps/service/
-COPY apps/cli/package.json apps/cli/
-COPY packages/eslint-config/package.json packages/eslint-config/
-COPY packages/typescript-config/package.json packages/typescript-config/
-COPY packages/ui/package.json packages/ui/
-
-# Dependencies stage
-FROM base AS dependencies
+COPY apps/*/package.json ./apps/
+COPY packages/*/package.json ./packages/
 
 # Install all dependencies (including dev dependencies for building)
 RUN pnpm install --frozen-lockfile
@@ -41,7 +37,7 @@ EXPOSE 3000 3001 3002
 ENTRYPOINT ["pnpm", "run", "cli"]
 CMD []
 
-# Builder stage - builds the application
+# Builder stage - builds the applications
 FROM dependencies AS builder
 
 # Copy all source code
@@ -50,52 +46,28 @@ COPY . .
 # Build all applications
 RUN pnpm run build
 
-# Production dependencies stage
-FROM base AS prod-dependencies
-
-# Install only production dependencies
-RUN pnpm install --frozen-lockfile --prod
-
-# Production stage
-FROM node:20-slim AS production
-
-# Install runtime system dependencies
-RUN apt-get update && apt-get install -y \
-    handbrake-cli \
-    sqlite3 \
-    ffmpeg \
-    && rm -rf /var/lib/apt/lists/*
-
-# Install pnpm
-RUN npm install -g pnpm
-
-WORKDIR /app
+# Production stage - final runtime image
+FROM base AS production
 
-# Copy package files
+# Copy package files for production dependencies
 COPY package.json pnpm-lock.yaml pnpm-workspace.yaml turbo.json ./
-COPY apps/web/package.json apps/web/
-COPY apps/service/package.json apps/service/
-COPY apps/cli/package.json apps/cli/
-COPY packages/eslint-config/package.json packages/eslint-config/
-COPY packages/typescript-config/package.json packages/typescript-config/
-COPY packages/ui/package.json packages/ui/
+COPY apps/*/package.json ./apps/
+COPY packages/*/package.json ./packages/
 
-# Copy production dependencies
-COPY --from=prod-dependencies /app/node_modules ./node_modules
+# Install only production dependencies
+RUN pnpm install --frozen-lockfile --prod
 
-# Copy built applications
+# Copy built applications from builder stage
 COPY --from=builder /app/apps/web/.next ./apps/web/.next
 COPY --from=builder /app/apps/web/public ./apps/web/public
 COPY --from=builder /app/apps/service/dist ./apps/service/dist
 COPY --from=builder /app/apps/cli/dist ./apps/cli/dist
 
-# Copy necessary source files for Next.js
-COPY apps/web/next.config.ts apps/web/
-COPY apps/web/next.config.js apps/web/
+# Copy necessary config files for Next.js
+COPY apps/web/next.config.ts apps/web/next.config.js ./apps/web/
 
 # Expose ports
 EXPOSE 3000 3001 3002
 
-# Set the CLI as the default entrypoint for production
-ENTRYPOINT ["pnpm", "run", "cli"]
-CMD []
+# Default command runs all services in production
+CMD ["pnpm", "start"]

+ 1 - 0
README.md

@@ -101,6 +101,7 @@ docker-compose down
 ### Docker Image Features
 
 The Docker image includes:
+
 - **Node.js 20** with pnpm package manager
 - **HandBrake CLI** for video processing
 - **FFmpeg** for media operations

+ 1 - 1
apps/service/package.json

@@ -9,7 +9,7 @@
     "build": "nest build",
     "dev": "nest start --watch",
     "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
-    "start": "nest start",
+    "start": "node dist/main",
     "start:dev": "nest start --watch",
     "start:debug": "nest start --debug --watch",
     "start:prod": "node dist/main",

+ 4 - 4
docker-compose.yml

@@ -32,7 +32,7 @@ services:
       - ./data:/app/data # Persist database files only
     environment:
       - NODE_ENV=production
-    # CLI is now the default entrypoint, can be overridden with command
-    # command: pnpm start  # Uncomment to run production servers instead of CLI
-    stdin_open: true # Keep stdin open for interactive CLI
-    tty: true # Allocate a pseudo-TTY for interactive CLI
+    # Runs all services (web + service) in production by default
+    # Override with command to run CLI: ["node", "apps/cli/dist/index.js"]
+    stdin_open: true # Keep stdin open for CLI if used
+    tty: true # Allocate a pseudo-TTY for CLI if used

+ 6 - 1
turbo.json

@@ -5,7 +5,7 @@
     "build": {
       "dependsOn": ["^build"],
       "inputs": ["$TURBO_DEFAULT$", ".env*"],
-      "outputs": [".next/**", "!.next/cache/**"]
+      "outputs": [".next/**", "!.next/cache/**", "dist/**"]
     },
     "lint": {
       "dependsOn": ["^lint"]
@@ -16,6 +16,11 @@
     "dev": {
       "cache": false,
       "persistent": true
+    },
+    "start": {
+      "dependsOn": ["build"],
+      "cache": false,
+      "persistent": true
     }
   }
 }