Next.js Docker部署 #

一、Docker概述 #

1.1 为什么使用Docker #

  • 环境一致性
  • 易于部署
  • 可扩展性
  • 资源隔离

1.2 部署方式 #

方式 说明
standalone 独立输出
static 静态导出

二、基础Dockerfile #

2.1 简单Dockerfile #

dockerfile
FROM node:20-alpine AS base

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

EXPOSE 3000
CMD ["npm", "start"]

2.2 构建镜像 #

bash
docker build -t nextjs-app .

2.3 运行容器 #

bash
docker run -p 3000:3000 nextjs-app

三、多阶段构建 #

3.1 优化Dockerfile #

dockerfile
FROM node:20-alpine AS base

FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci

FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]

3.2 启用standalone输出 #

typescript
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
    output: 'standalone',
}

export default nextConfig

四、环境变量 #

4.1 构建时变量 #

dockerfile
ARG NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
bash
docker build --build-arg NEXT_PUBLIC_API_URL=https://api.example.com -t nextjs-app .

4.2 运行时变量 #

dockerfile
ENV DATABASE_URL=""
bash
docker run -e DATABASE_URL=postgresql://... nextjs-app

4.3 使用.env文件 #

bash
docker run --env-file .env nextjs-app

五、Docker Compose #

5.1 基本配置 #

yaml
version: '3.8'

services:
    web:
        build: .
        ports:
            - "3000:3000"
        environment:
            - DATABASE_URL=postgresql://postgres:postgres@db:5432/mydb
        depends_on:
            - db
    
    db:
        image: postgres:15
        environment:
            - POSTGRES_USER=postgres
            - POSTGRES_PASSWORD=postgres
            - POSTGRES_DB=mydb
        volumes:
            - postgres_data:/var/lib/postgresql/data

volumes:
    postgres_data:

5.2 启动服务 #

bash
docker-compose up -d

5.3 生产配置 #

yaml
version: '3.8'

services:
    web:
        image: nextjs-app:latest
        ports:
            - "3000:3000"
        environment:
            - NODE_ENV=production
            - DATABASE_URL=${DATABASE_URL}
        restart: always
        healthcheck:
            test: ["CMD", "curl", "-f", "http://localhost:3000"]
            interval: 30s
            timeout: 10s
            retries: 3

六、优化技巧 #

6.1 缓存优化 #

dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

6.2 镜像大小优化 #

dockerfile
FROM node:20-alpine AS runner
WORKDIR /app

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

6.3 安全优化 #

dockerfile
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
USER nextjs

七、CI/CD集成 #

7.1 GitHub Actions #

yaml
name: Docker Build

on:
    push:
        branches: [main]

jobs:
    build:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v4
            
            - name: Build Docker image
                run: docker build -t nextjs-app .
            
            - name: Push to Registry
                run: |
                    docker tag nextjs-app registry.example.com/nextjs-app
                    docker push registry.example.com/nextjs-app

7.2 自动部署 #

yaml
- name: Deploy
    run: |
        ssh user@server 'docker pull registry.example.com/nextjs-app'
        ssh user@server 'docker-compose up -d'

八、最佳实践 #

8.1 使用多阶段构建 #

减小镜像大小,提高安全性。

8.2 使用非root用户 #

dockerfile
USER nextjs

8.3 健康检查 #

dockerfile
HEALTHCHECK --interval=30s CMD curl -f http://localhost:3000/ || exit 1

九、总结 #

Docker部署要点:

要点 说明
多阶段构建 减小镜像大小
standalone 独立输出
环境变量 运行时配置
Docker Compose 多服务编排
CI/CD 自动化部署

下一步,让我们学习环境变量!

最后更新:2026-03-28