Nuxt.js Docker部署 #

一、Docker概述 #

Docker 是一种容器化技术,可以将应用及其依赖打包成可移植的容器镜像。

1.1 Docker优势 #

  • 环境一致性:开发、测试、生产环境一致
  • 快速部署:秒级启动容器
  • 资源隔离:独立的运行环境
  • 可移植性:在任何支持 Docker 的平台运行

二、Dockerfile #

2.1 基础Dockerfile #

Dockerfile

dockerfile
FROM node:20-alpine AS builder

WORKDIR /app

COPY package.json pnpm-lock.yaml ./

RUN npm install -g pnpm && pnpm install --frozen-lockfile

COPY . .

RUN pnpm run build

FROM node:20-alpine AS runtime

WORKDIR /app

COPY --from=builder /app/.output ./.output

ENV NUXT_HOST=0.0.0.0
ENV NUXT_PORT=3000

EXPOSE 3000

CMD ["node", ".output/server/index.mjs"]

2.2 多阶段构建 #

dockerfile
FROM node:20-alpine AS deps

WORKDIR /app

COPY package.json pnpm-lock.yaml ./

RUN npm install -g pnpm && \
    pnpm install --frozen-lockfile

FROM node:20-alpine AS builder

WORKDIR /app

COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NUXT_TELEMETRY_DISABLED=1

RUN npm install -g pnpm && \
    pnpm run build

FROM node:20-alpine AS runtime

WORKDIR /app

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

COPY --from=builder /app/.output ./.output

RUN chown -R nuxt:nodejs /app

USER nuxt

ENV NUXT_HOST=0.0.0.0
ENV NUXT_PORT=3000
ENV NODE_ENV=production

EXPOSE 3000

CMD ["node", ".output/server/index.mjs"]

2.3 静态站点Dockerfile #

dockerfile
FROM node:20-alpine AS builder

WORKDIR /app

COPY package.json pnpm-lock.yaml ./

RUN npm install -g pnpm && pnpm install --frozen-lockfile

COPY . .

RUN pnpm run generate

FROM nginx:alpine

COPY --from=builder /app/.output/public /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

三、构建镜像 #

3.1 构建命令 #

bash
docker build -t my-nuxt-app .

3.2 指定标签 #

bash
docker build -t my-nuxt-app:v1.0.0 .

3.3 构建参数 #

bash
docker build \
  --build-arg NUXT_PUBLIC_API_BASE=https://api.example.com \
  -t my-nuxt-app .

四、运行容器 #

4.1 基本运行 #

bash
docker run -p 3000:3000 my-nuxt-app

4.2 环境变量 #

bash
docker run \
  -p 3000:3000 \
  -e NUXT_PUBLIC_API_BASE=https://api.example.com \
  -e NUXT_SECRET_KEY=your-secret-key \
  my-nuxt-app

4.3 后台运行 #

bash
docker run -d -p 3000:3000 --name nuxt-app my-nuxt-app

4.4 数据卷 #

bash
docker run \
  -p 3000:3000 \
  -v $(pwd)/logs:/app/logs \
  my-nuxt-app

五、Docker Compose #

5.1 基本配置 #

docker-compose.yml

yaml
version: '3.8'

services:
  nuxt:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NUXT_PUBLIC_API_BASE=https://api.example.com
      - NUXT_SECRET_KEY=your-secret-key
    restart: unless-stopped

5.2 完整配置 #

yaml
version: '3.8'

services:
  nuxt:
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - NUXT_PUBLIC_API_BASE=${NUXT_PUBLIC_API_BASE}
    ports:
      - "3000:3000"
    environment:
      - NUXT_HOST=0.0.0.0
      - NUXT_PORT=3000
      - NUXT_PUBLIC_API_BASE=${NUXT_PUBLIC_API_BASE}
      - NUXT_SECRET_KEY=${NUXT_SECRET_KEY}
      - DATABASE_URL=${DATABASE_URL}
    depends_on:
      - db
      - redis
    networks:
      - app-network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - app-network
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    networks:
      - app-network
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - nuxt
    networks:
      - app-network
    restart: unless-stopped

networks:
  app-network:
    driver: bridge

volumes:
  postgres-data:
  redis-data:

5.3 启动服务 #

bash
docker-compose up -d

5.4 查看日志 #

bash
docker-compose logs -f nuxt

5.5 停止服务 #

bash
docker-compose down

六、Nginx配置 #

6.1 反向代理 #

nginx.conf

nginx
events {
    worker_connections 1024;
}

http {
    upstream nuxt {
        server nuxt:3000;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://nuxt;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_cache_bypass $http_upgrade;
        }
    }
}

6.2 HTTPS配置 #

nginx
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;

    location / {
        proxy_pass http://nuxt;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

七、CI/CD集成 #

7.1 GitHub Actions #

.github/workflows/docker.yml

yaml
name: Docker Build and Push

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ secrets.DOCKER_USERNAME }}/my-nuxt-app:latest

7.2 GitLab CI #

.gitlab-ci.yml

yaml
stages:
  - build
  - deploy

build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
    - docker build -t $DOCKER_USERNAME/my-nuxt-app:$CI_COMMIT_SHA .
    - docker push $DOCKER_USERNAME/my-nuxt-app:$CI_COMMIT_SHA

deploy:
  stage: deploy
  image: docker:latest
  script:
    - docker pull $DOCKER_USERNAME/my-nuxt-app:$CI_COMMIT_SHA
    - docker-compose up -d

八、最佳实践 #

8.1 镜像优化 #

  • 使用 Alpine 基础镜像
  • 多阶段构建减小镜像大小
  • 缓存依赖层

8.2 安全配置 #

  • 使用非 root 用户运行
  • 不在镜像中存储敏感信息
  • 定期更新基础镜像

8.3 健康检查 #

dockerfile
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/api/health || exit 1

九、总结 #

本章介绍了 Nuxt.js Docker 部署:

  • Dockerfile 编写
  • 多阶段构建优化
  • Docker Compose 配置
  • Nginx 反向代理
  • CI/CD 集成
  • 最佳实践

Docker 部署适合需要完全控制部署环境的场景,下一章我们将学习环境变量配置。

最后更新:2026-03-28