{T}

Docker 容器化部署前端项目实战

概述

本文讲解前端项目的两种容器化部署方式:Volume 映射(快速测试)和构建镜像(生产推荐),涵盖 Docker Compose 配置、端口映射、Volume 映射、Nginx 配置及多阶段构建 Dockerfile。

前置知识

学习目标

  1. 理解两种前端容器化方式的优劣与适用场景
  2. 掌握 Docker Compose 端口映射与 Volume 映射配置
  3. 熟练编写前端多阶段构建 Dockerfile
  4. 能够完成从构建到部署的完整流程

一、两种容器化方式对比

维度Volume 映射构建镜像(推荐)
原理Nginx 官方镜像 + 宿主机目录映射编写 Dockerfile,代码打包进镜像
环境独立性依赖宿主机目录完全独立
部署速度快(无需构建)首次慢,后续秒级
版本管理镜像版本控制
CI/CD 友好
适用场景快速测试、开发环境生产环境、多环境部署

二、方式一:Docker + Nginx + Volume 映射

Docker Compose 配置

yaml
version: '3'
services:
  nginx:
    restart: always
    image: nginx
    container_name: frontend-nginx
    environment:
      - TZ=Asia/Shanghai
    ports:
      - "4080:80"       # 宿主机端口:容器端口
    volumes:
      - /home/website:/usr/share/nginx/html      # 网站目录
      - /etc/nginx/conf.d:/etc/nginx/conf.d      # Nginx 配置
      - /var/log/nginx:/var/log/nginx            # 日志目录

端口映射原理

code
浏览器 → http://server-ip:4080
       → Docker 映射到容器 80 端口
       → Nginx 监听 80 端口,响应请求

关键规则:

  • 宿主机端口不能冲突
  • 容器端口必须与 Nginx listen 配置一致
  • 修改 Nginx 配置后需重启容器:docker restart frontend-nginx

Nginx 配置示例

nginx
# /etc/nginx/conf.d/site.conf
server {
    listen 80;
    server_name example.com;

    location / {
        root /usr/share/nginx/html/my-app;
        index index.html;
        try_files $uri $uri/ /index.html;  # SPA 路由支持
    }
}

部署流程

bash
# 1. 构建前端项目
npm run build

# 2. 上传产物到服务器
rsync -avz dist/ user@server:/home/website/my-app/

# 3. 启动容器
docker compose up -d

# 4. 更新部署(无需重建容器)
rsync -avz dist/ user@server:/home/website/my-app/
docker exec frontend-nginx nginx -s reload

三、方式二:构建 Docker 镜像(推荐)

.dockerignore

plaintext
node_modules
dist
.git
.github
.DS_Store
*.log
.env*

多阶段构建 Dockerfile(Vue/React SPA)

dockerfile
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 生产阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

多阶段构建 Dockerfile(Nuxt3 SSR)

dockerfile
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
RUN npm config set registry https://registry.npmmirror.com
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 生产阶段
FROM node:18-alpine AS production
WORKDIR /app
COPY --from=builder /app/.output ./.output
EXPOSE 3000
ENV NODE_ENV=production
CMD ["node", ".output/server/index.mjs"]

Nuxt3 的 .output 目录通过 bundleDependencies 自动打包所有运行时依赖,生产阶段无需 npm install


四、镜像构建与运行

bash
# 构建镜像
docker build -t my-frontend:1.0 .

# 运行容器
docker run -d --name frontend -p 8080:80 my-frontend:1.0

# 查看日志
docker logs -f frontend

# 停止/删除
docker stop frontend && docker rm frontend

# 强制重新构建(清除缓存)
docker build --no-cache -t my-frontend:1.0 .

五、环境变量配置

命令行传递

bash
docker run -d -p 3000:3000 \
  -e BASE_URL=http://api.example.com \
  -e API_KEY=xxx \
  my-nuxt-app:1.0

Docker Compose + .env 文件(推荐)

yaml
version: '3.8'
services:
  nuxt-app:
    image: nuxt-app:1.0
    container_name: nuxt-app-prod
    restart: always
    ports:
      - "3000:3000"
    env_file:
      - .env.production
bash
# .env.production
BASE_URL=http://api.example.com
API_KEY=your_api_key
NODE_ENV=production

常见问题

问题原因解决方案
端口被占用宿主机端口冲突修改 ports 映射或停止占用进程
页面 404SPA 路由未配置 try_filesNginx 添加 try_files $uri /index.html
容器启动即退出启动命令错误docker logs 查看错误日志
构建缓存导致旧代码Docker 层缓存docker build --no-cache
node_modules 兼容问题跨平台 native 模块.dockerignore 排除,容器内重新安装

问题排查流程

bash
docker ps -a                           # 查看容器状态
docker logs -f <container>             # 查看日志
docker exec -it <container> sh         # 进入容器调试
netstat -tlnp | grep <port>           # 检查端口占用
docker build --no-cache -t app:1.0 .   # 重新构建

最佳实践

  • 生产环境优先使用构建镜像方式,确保环境一致性
  • 使用 .dockerignore 排除 node_modules,容器内安装避免跨平台问题
  • 容器构建使用 npm(而非 pnpm),避免软链接在容器内的路径问题
  • 镜像标签使用语义化版本号,便于回滚
  • 敏感配置通过 .env 文件或 Docker Secret 注入,不写入镜像

延伸阅读


上一篇:Docker 支持重启策略,是否还需要 PM2 下一篇:Docker 镜像构建优化实战