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