主要区别是使用前端编译后的standalone目录, 在里面使用
node server.js来运行, 会比npm run start更轻量
这基本上是一个缩小尺寸的 NextJS 服务器,它只包含它的动态部分。观察表明 node_modules 仅占项目 node_modules 的 5% 左右,这在尺寸上是显着减小的(在我们有限的测试中)
后端
正常打包
前端
next.config.ts
import type { NextConfig } from "next";
  
const nextConfig: NextConfig = {
  /* config options here */
  rewrites: async () => [
    {
      source: "/api/:path*",
      destination: "http://localhost:8080/api/:path*",
    },
    
  ],
  // 使用 standalone 模式替代静态导出
  output: "standalone",
  // output: "export",
  // distDir: "out",
  typescript: {
    ignoreBuildErrors: true
  },
  eslint: {
    ignoreDuringBuilds: true
  }
};
  
export default nextConfig;
Dockerfile
# 最终运行镜像
FROM node:22-alpine AS runner
WORKDIR /app
# 安装必要的依赖
RUN apk add --no-cache libc6-compat tzdata
# 设置时区为中国标准时间
ENV TZ=Asia/Shanghai
  
# 复制GitHub Actions构建的Go后端
COPY czlconnect-backend /app/backend/
# 复制Next.js standalone构建结果
COPY web/.next/standalone /app/frontend/
COPY web/.next/static /app/frontend/.next/static
COPY web/public /app/frontend/public
# 添加启动脚本
COPY scripts/start.sh /app/
RUN chmod +x /app/start.sh
  
# 设置工作目录环境变量
ENV PORT=3000
ENV NODE_ENV=production
ENV GIN_MODE=release
# 设置用户
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN chown -R nextjs:nodejs /app/frontend
USER nextjs
# 暴露端口
EXPOSE 3000 8080
# 启动应用
CMD ["/app/start.sh"]
启动脚本 start.sh
#!/bin/sh
  
# 确保时区设置正确
export TZ=Asia/Shanghai
  
# 启动后端应用
cd /app/backend
./czlconnect-backend &
# 启动Next.js应用
cd /app/frontend
# 在standalone模式下,不需要npm install和npm run build
# 直接用node启动server.js
node server.js
# 不需要额外的保持容器运行的逻辑,因为node进程会保持运行
# 如果node进程退出,容器也会退出,Docker可以重启容器
github actions示例
name: 构建并推送Docker镜像
  
on:
  push:
    branches: [ main ]
  workflow_dispatch:
  
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - name: 检出代码
      uses: actions/checkout@v4
    - name: 设置Go环境
      uses: actions/setup-go@v5
      with:
        go-version: '1.23'
    - name: 设置Node.js环境
      uses: actions/setup-node@v4
      with:
        node-version: '22'
        cache: 'npm'
        cache-dependency-path: web/package-lock.json
    - name: 构建后端
      run: |
        go mod download
        # 添加CGO_ENABLED=0确保静态编译,添加时区数据
        CGO_ENABLED=0 go build -ldflags="-w -s" -tags timetzdata -o czlconnect-backend .
    - name: 构建前端
      run: |
        cd web
        # 安装依赖并构建(使用standalone模式)
        npm ci
        npm run build
        # 检查standalone构建文件是否生成成功
        if [ ! -d ".next/standalone" ]; then
          echo "Next.js standalone构建失败,缺少standalone目录"
          exit 1
        fi
    - name: 设置Docker Buildx
      uses: docker/setup-buildx-action@v3
    - name: 登录到Docker Hub
      if: github.event_name != 'pull_request'
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKER_HUB_USERNAME }}
        password: ${{ secrets.DOCKER_HUB_TOKEN }}
    - name: 构建并推送Docker镜像
      uses: docker/build-push-action@v6
      with:
        context: .
        push: true
        tags: ${{ secrets.DOCKER_HUB_USERNAME }}/czlconnect:latest
        # 添加构建参数
        build-args: |
          BUILD_DATE=${{ github.event.repository.updated_at }}
          VCS_REF=${{ github.sha }}
评论区