Docker 前端部署别再手动配环境了毒舌时刻这代码写得跟网红滤镜似的——仅供参考。各位前端同行咱们今天聊聊 Docker。别告诉我你还在手动配环境那感觉就像每次吃饭都要重新买菜做饭——能吃但累死人。为什么你需要 Docker最近看到一个项目开发环境、测试环境、生产环境配置都不一样每次部署都要改一堆配置。我就想问你是在写代码还是在玩找不同反面教材# 反面教材手动部署流程 # 开发环境 $ npm install $ npm run dev # 测试环境 $ npm install --production $ npm run build $ scp -r dist/ usertest-server:/var/www/ # 报错Node 版本不对 # 报错依赖安装失败 # 报错环境变量缺失 # # 生产环境 $ npm install --production $ npm run build $ rsync -avz dist/ userprod-server:/var/www/ # 又报一堆错 # 环境不一致问题难复现毒舌点评这流程部署一次要 2 小时你是在写代码还是在做运维Docker 的正确姿势1. 基础 Dockerfile# 正确姿势多阶段构建 # Dockerfile # 阶段1构建 FROM node:20-alpine AS builder WORKDIR /app # 先复制依赖文件利用缓存 COPY package*.json ./ RUN npm ci # 复制源代码 COPY . . # 构建 RUN npm run build # 阶段2运行 FROM node:20-alpine AS runner WORKDIR /app # 只复制必要文件 COPY --frombuilder /app/dist ./dist COPY --frombuilder /app/package*.json ./ # 只安装生产依赖 RUN npm ci --onlyproduction # 暴露端口 EXPOSE 3000 # 启动 CMD [node, dist/server.js]2. Next.js 专用# 正确姿势Next.js Docker 配置 # Dockerfile FROM node:20-alpine AS base # 安装依赖 FROM base AS deps RUN apk add --no-cache libc6-compat WORKDIR /app COPY package*.json ./ RUN npm ci # 构建 FROM base AS builder WORKDIR /app COPY --fromdeps /app/node_modules ./node_modules COPY . . ENV NEXT_TELEMETRY_DISABLED 1 RUN npm run build # 运行 FROM base AS runner WORKDIR /app ENV NODE_ENV production ENV NEXT_TELEMETRY_DISABLED 1 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY --frombuilder /app/public ./public RUN mkdir .next RUN chown nextjs:nodejs .next COPY --frombuilder --chownnextjs:nodejs /app/.next/standalone ./ COPY --frombuilder --chownnextjs:nodejs /app/.next/static ./.next/static USER nextjs EXPOSE 3000 ENV PORT 3000 ENV HOSTNAME 0.0.0.0 CMD [node, server.js]3. Docker Compose# 正确姿势docker-compose.yml version: 3.8 services: # 前端应用 app: build: context: . dockerfile: Dockerfile ports: - 3000:3000 environment: - NODE_ENVproduction - API_URLhttp://api:8080 depends_on: - api networks: - frontend-network # Nginx 反向代理 nginx: image: nginx:alpine ports: - 80:80 - 443:443 volumes: - ./nginx.conf:/etc/nginx/nginx.conf - ./ssl:/etc/nginx/ssl depends_on: - app networks: - frontend-network # 后端 API示例 api: image: my-api:latest ports: - 8080:8080 environment: - DATABASE_URLpostgres://db:5432/mydb networks: - frontend-network networks: frontend-network: driver: bridge4. Nginx 配置# nginx.conf upstream app { server app:3000; } server { listen 80; server_name example.com; # 重定向到 HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/nginx/ssl/cert.pem; ssl_certificate_key /etc/nginx/ssl/key.pem; # Gzip gzip on; gzip_types text/plain text/css application/json application/javascript; # 静态资源缓存 location /_next/static { alias /app/.next/static; expires 1y; add_header Cache-Control public, immutable; } location /static { alias /app/public; expires 1y; add_header Cache-Control public, immutable; } # 代理到应用 location / { proxy_pass http://app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }毒舌点评这才叫现代部署一次构建到处运行环境完全一致。实战技巧Docker 最佳实践1. 优化镜像大小# 正确姿势最小化镜像 FROM node:20-alpine # 使用非 root 用户 RUN addgroup -g 1001 -S nodejs RUN adduser -S nextjs -u 1001 # 只复制必要文件 COPY --chownnextjs:nodejs package*.json ./ RUN npm ci --onlyproduction npm cache clean --force COPY --chownnextjs:nodejs . . USER nextjs EXPOSE 3000 CMD [node, server.js]2. 开发环境# docker-compose.dev.yml version: 3.8 services: app: build: context: . dockerfile: Dockerfile.dev ports: - 3000:3000 volumes: - .:/app - /app/node_modules environment: - NODE_ENVdevelopment - CHOKIDAR_USEPOLLINGtrue command: npm run dev# Dockerfile.dev FROM node:20-alpine WORKDIR /app # 安装依赖 COPY package*.json ./ RUN npm install EXPOSE 3000 CMD [npm, run, dev]3. CI/CD 集成# .github/workflows/docker.yml name: Docker Build and Push on: push: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Set up Docker Buildx uses: docker/setup-buildx-actionv3 - name: Login to Docker Hub uses: docker/login-actionv3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push uses: docker/build-push-actionv5 with: context: . push: true tags: | ${{ secrets.DOCKER_USERNAME }}/myapp:latest ${{ secrets.DOCKER_USERNAME }}/myapp:${{ github.sha }} cache-from: typegha cache-to: typegha,modemax4. 环境变量管理# Dockerfile FROM node:20-alpine # 构建参数 ARG NODE_ENVproduction ARG API_URL ENV NODE_ENV${NODE_ENV} ENV API_URL${API_URL} WORKDIR /app COPY . . RUN npm ci npm run build EXPOSE 3000 CMD [node, dist/server.js]# 构建时传入参数 docker build \ --build-arg NODE_ENVproduction \ --build-arg API_URLhttps://api.example.com \ -t myapp:latest . # 运行时传入环境变量 docker run -e API_URLhttps://api.example.com -p 3000:3000 myapp:latest5. 健康检查# Dockerfile FROM node:20-alpine WORKDIR /app COPY . . RUN npm ci --onlyproduction EXPOSE 3000 # 健康检查 HEALTHCHECK --interval30s --timeout3s --start-period5s --retries3 \ CMD curl -f http://localhost:3000/api/health || exit 1 CMD [node, server.js]6. 常见陷阱# 陷阱1不使用 .dockerignore # .dockerignore node_modules npm-debug.log .next .git .env .env.local .env.production # 陷阱2不使用多阶段构建 FROM node:20-alpine COPY . . RUN npm ci RUN npm run build # ❌ 镜像包含所有依赖和源码体积巨大 # 正确做法使用多阶段构建 ✅ # 陷阱3使用 root 用户运行 # ❌ 安全风险 # 正确做法创建非 root 用户 ✅ RUN adduser -S appuser USER appuser # 陷阱4不清理缓存 RUN npm ci # ❌ 缓存留在镜像中 # 正确做法清理缓存 ✅ RUN npm ci npm cache clean --force最后想说的Docker 不是可选的是现代部署的标准。别再手动配环境了——用上 Docker你的部署会简单 100 倍。记住好的部署应该是一致的开发、测试、生产环境完全一致。Docker 让这一切变得简单。
Docker 前端部署:别再手动配环境了
发布时间:2026/5/27 14:19:40
Docker 前端部署别再手动配环境了毒舌时刻这代码写得跟网红滤镜似的——仅供参考。各位前端同行咱们今天聊聊 Docker。别告诉我你还在手动配环境那感觉就像每次吃饭都要重新买菜做饭——能吃但累死人。为什么你需要 Docker最近看到一个项目开发环境、测试环境、生产环境配置都不一样每次部署都要改一堆配置。我就想问你是在写代码还是在玩找不同反面教材# 反面教材手动部署流程 # 开发环境 $ npm install $ npm run dev # 测试环境 $ npm install --production $ npm run build $ scp -r dist/ usertest-server:/var/www/ # 报错Node 版本不对 # 报错依赖安装失败 # 报错环境变量缺失 # # 生产环境 $ npm install --production $ npm run build $ rsync -avz dist/ userprod-server:/var/www/ # 又报一堆错 # 环境不一致问题难复现毒舌点评这流程部署一次要 2 小时你是在写代码还是在做运维Docker 的正确姿势1. 基础 Dockerfile# 正确姿势多阶段构建 # Dockerfile # 阶段1构建 FROM node:20-alpine AS builder WORKDIR /app # 先复制依赖文件利用缓存 COPY package*.json ./ RUN npm ci # 复制源代码 COPY . . # 构建 RUN npm run build # 阶段2运行 FROM node:20-alpine AS runner WORKDIR /app # 只复制必要文件 COPY --frombuilder /app/dist ./dist COPY --frombuilder /app/package*.json ./ # 只安装生产依赖 RUN npm ci --onlyproduction # 暴露端口 EXPOSE 3000 # 启动 CMD [node, dist/server.js]2. Next.js 专用# 正确姿势Next.js Docker 配置 # Dockerfile FROM node:20-alpine AS base # 安装依赖 FROM base AS deps RUN apk add --no-cache libc6-compat WORKDIR /app COPY package*.json ./ RUN npm ci # 构建 FROM base AS builder WORKDIR /app COPY --fromdeps /app/node_modules ./node_modules COPY . . ENV NEXT_TELEMETRY_DISABLED 1 RUN npm run build # 运行 FROM base AS runner WORKDIR /app ENV NODE_ENV production ENV NEXT_TELEMETRY_DISABLED 1 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY --frombuilder /app/public ./public RUN mkdir .next RUN chown nextjs:nodejs .next COPY --frombuilder --chownnextjs:nodejs /app/.next/standalone ./ COPY --frombuilder --chownnextjs:nodejs /app/.next/static ./.next/static USER nextjs EXPOSE 3000 ENV PORT 3000 ENV HOSTNAME 0.0.0.0 CMD [node, server.js]3. Docker Compose# 正确姿势docker-compose.yml version: 3.8 services: # 前端应用 app: build: context: . dockerfile: Dockerfile ports: - 3000:3000 environment: - NODE_ENVproduction - API_URLhttp://api:8080 depends_on: - api networks: - frontend-network # Nginx 反向代理 nginx: image: nginx:alpine ports: - 80:80 - 443:443 volumes: - ./nginx.conf:/etc/nginx/nginx.conf - ./ssl:/etc/nginx/ssl depends_on: - app networks: - frontend-network # 后端 API示例 api: image: my-api:latest ports: - 8080:8080 environment: - DATABASE_URLpostgres://db:5432/mydb networks: - frontend-network networks: frontend-network: driver: bridge4. Nginx 配置# nginx.conf upstream app { server app:3000; } server { listen 80; server_name example.com; # 重定向到 HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/nginx/ssl/cert.pem; ssl_certificate_key /etc/nginx/ssl/key.pem; # Gzip gzip on; gzip_types text/plain text/css application/json application/javascript; # 静态资源缓存 location /_next/static { alias /app/.next/static; expires 1y; add_header Cache-Control public, immutable; } location /static { alias /app/public; expires 1y; add_header Cache-Control public, immutable; } # 代理到应用 location / { proxy_pass http://app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }毒舌点评这才叫现代部署一次构建到处运行环境完全一致。实战技巧Docker 最佳实践1. 优化镜像大小# 正确姿势最小化镜像 FROM node:20-alpine # 使用非 root 用户 RUN addgroup -g 1001 -S nodejs RUN adduser -S nextjs -u 1001 # 只复制必要文件 COPY --chownnextjs:nodejs package*.json ./ RUN npm ci --onlyproduction npm cache clean --force COPY --chownnextjs:nodejs . . USER nextjs EXPOSE 3000 CMD [node, server.js]2. 开发环境# docker-compose.dev.yml version: 3.8 services: app: build: context: . dockerfile: Dockerfile.dev ports: - 3000:3000 volumes: - .:/app - /app/node_modules environment: - NODE_ENVdevelopment - CHOKIDAR_USEPOLLINGtrue command: npm run dev# Dockerfile.dev FROM node:20-alpine WORKDIR /app # 安装依赖 COPY package*.json ./ RUN npm install EXPOSE 3000 CMD [npm, run, dev]3. CI/CD 集成# .github/workflows/docker.yml name: Docker Build and Push on: push: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Set up Docker Buildx uses: docker/setup-buildx-actionv3 - name: Login to Docker Hub uses: docker/login-actionv3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push uses: docker/build-push-actionv5 with: context: . push: true tags: | ${{ secrets.DOCKER_USERNAME }}/myapp:latest ${{ secrets.DOCKER_USERNAME }}/myapp:${{ github.sha }} cache-from: typegha cache-to: typegha,modemax4. 环境变量管理# Dockerfile FROM node:20-alpine # 构建参数 ARG NODE_ENVproduction ARG API_URL ENV NODE_ENV${NODE_ENV} ENV API_URL${API_URL} WORKDIR /app COPY . . RUN npm ci npm run build EXPOSE 3000 CMD [node, dist/server.js]# 构建时传入参数 docker build \ --build-arg NODE_ENVproduction \ --build-arg API_URLhttps://api.example.com \ -t myapp:latest . # 运行时传入环境变量 docker run -e API_URLhttps://api.example.com -p 3000:3000 myapp:latest5. 健康检查# Dockerfile FROM node:20-alpine WORKDIR /app COPY . . RUN npm ci --onlyproduction EXPOSE 3000 # 健康检查 HEALTHCHECK --interval30s --timeout3s --start-period5s --retries3 \ CMD curl -f http://localhost:3000/api/health || exit 1 CMD [node, server.js]6. 常见陷阱# 陷阱1不使用 .dockerignore # .dockerignore node_modules npm-debug.log .next .git .env .env.local .env.production # 陷阱2不使用多阶段构建 FROM node:20-alpine COPY . . RUN npm ci RUN npm run build # ❌ 镜像包含所有依赖和源码体积巨大 # 正确做法使用多阶段构建 ✅ # 陷阱3使用 root 用户运行 # ❌ 安全风险 # 正确做法创建非 root 用户 ✅ RUN adduser -S appuser USER appuser # 陷阱4不清理缓存 RUN npm ci # ❌ 缓存留在镜像中 # 正确做法清理缓存 ✅ RUN npm ci npm cache clean --force最后想说的Docker 不是可选的是现代部署的标准。别再手动配环境了——用上 Docker你的部署会简单 100 倍。记住好的部署应该是一致的开发、测试、生产环境完全一致。Docker 让这一切变得简单。