Docker容器化部署前端项目实战
Docker容器化部署前端项目实战
学习目标:掌握 Docker 容器化部署、Docker Compose 配置、Dockerfile 编写、多阶段构建、镜像优化。
一、容器化部署概述
1.1 容器化 vs 直装部署对比
code
部署方式对比:
│
├── 直装部署(传统方式)
│ ├── 优点
│ │ ├── 简单直接
│ │ ├── 资源占用少
│ │ └── 调试方便
│ │
│ ├── 缺点
│ │ ├── 环境依赖强
│ │ ├── 部署复杂
│ │ ├── 环境不一致问题
│ │ └── 难以迁移
│ │
│ └── 适用场景
│ ├── 单机部署
│ ├── 环境固定
│ └── 小型项目
│
└── 容器化部署(推荐)
├── 优点
│ ├── 环境隔离
│ ├── 一致性强
│ ├── 易于迁移
│ ├── 快速部署
│ └── 版本管理
│
├── 缺点
│ ├── 学习成本
│ ├── 资源占用略高
│ └── 调试稍复杂
│
└── 适用场景
├── 多环境部署
├── 微服务架构
├── CI/CD 流水线
└── 大型项目 1.2 容器化部署核心优势
code
容器化部署核心优势:
│
├── 1. 环境隔离
│ ├── 网络隔离:不同容器端口独立
│ ├── 文件系统隔离:容器间互不影响
│ ├── 进程隔离:独立的进程空间
│ └── 环境变量隔离:独立的环境配置
│
├── 2. 环境一致性
│ ├── 开发环境 = 生产环境
│ ├── 固定的运行环境
│ ├── 无需担心依赖冲突
│ └── "一次构建,到处运行"
│
├── 3. 快速部署
│ ├── 秒级启动
│ ├── 一键部署
│ ├── 快速回滚
│ └── 弹性扩缩容
│
└── 4. 版本管理
├── 镜像版本控制
├── 快速回滚到历史版本
├── 镜像仓库管理
└── CI/CD 集成1.3 前端容器化两种方式
code
前端容器化两种方式:
│
├── 方式一:Docker + Nginx + Volume 映射
│ ├── 原理
│ │ ├── 使用 Nginx 官方镜像
│ │ ├── 宿主机目录映射到容器
│ │ └── Nginx 提供静态资源服务
│ │
│ ├── 优点
│ │ ├── 配置简单
│ │ ├── 灵活性高
│ │ ├── 无需构建镜像
│ │ └── 便于调试
│ │
│ ├── 缺点
│ │ ├── 依赖宿主机目录
│ │ ├── 迁移稍复杂
│ │ └── 环境不够独立
│ │
│ └── 适用场景
│ ├── 快速测试
│ ├── 开发环境
│ └── 需要频繁修改
│
└── 方式二:构建 Docker 镜像(推荐)
├── 原理
│ ├── 编写 Dockerfile
│ ├── 将代码打包到镜像中
│ ├── 基于 Nginx 镜像构建
│ └── 镜像即应用
│
├── 优点
│ ├── 环境完全独立
│ ├── 一键部署
│ ├── 易于迁移
│ ├── 版本管理清晰
│ └── CI/CD 友好
│
├── 缺点
│ ├── 需要学习 Dockerfile
│ ├── 构建时间较长
│ └── 镜像管理成本
│
└── 适用场景
├── 生产环境
├── 多环境部署
├── CI/CD 流水线
└── 大型项目 二、方式一:Docker + Nginx + Volume 映射
2.1 Docker Compose 基础配置
docker-compose.yml 基础配置:
yaml
# docker-compose.yml
version: '3' # Docker Compose 版本
services:
nginx: # 服务名称
restart: always # 重启策略:总是重启
image: nginx # 使用官方 Nginx 镜像
container_name: nginx # 容器名称(唯一)
environment: # 环境变量
- TZ=Asia/Shanghai # 设置时区
ports: # 端口映射
- "4080:80" # 宿主机端口:容器端口
volumes: # 目录映射
- /home/website:/usr/share/nginx/html # 网站目录映射配置详解:
code
Docker Compose 配置详解:
│
├── version: '3'
│ ├── Docker Compose 配置文件版本
│ ├── 常用版本:2、2.1、3、3.1、3.8
│ └── 推荐使用 3.x 版本
│
├── services
│ ├── 定义服务列表
│ ├── 每个服务对应一个容器
│ └── 可以定义多个服务
│
├── restart: always
│ ├── no:不自动重启(默认)
│ ├── always:总是重启
│ ├── on-failure:失败时重启
│ └── unless-stopped:除非手动停止
│
├── image: nginx
│ ├── 使用官方镜像
│ ├── 格式:镜像名:标签
│ └── 默认使用 latest 标签
│
├── container_name: nginx
│ ├── 容器名称(必须唯一)
│ ├── 不指定则自动生成
│ └── 建议:项目名-服务名
│
├── environment
│ ├── 环境变量配置
│ ├── TZ=Asia/Shanghai:设置时区
│ └── 可以配置多个环境变量
│
├── ports
│ ├── 端口映射:宿主机端口:容器端口
│ ├── 可以映射多个端口
│ └── 注意端口冲突
│
└── volumes
├── 目录映射:宿主机路径:容器路径
├── 可以映射多个目录
└── 支持相对路径和绝对路径2.2 端口映射原理详解
code
端口映射原理:
│
├── 概念
│ ├── 宿主机端口:外部访问的端口
│ ├── 容器端口:容器内部服务端口
│ └── 映射关系:宿主机端口 → 容器端口
│
├── 示例解析
│ ├── "4080:80"
│ │ ├── 宿主机端口:4080
│ │ ├── 容器端口:80(Nginx 默认)
│ │ └── 访问:http://server-ip:4080
│ │
│ ├── "4082:8000"
│ │ ├── 宿主机端口:4082
│ │ ├── 容器端口:8000(Nginx 监听 8000)
│ │ └── 访问:http://server-ip:4082
│ │
│ └── "9000:80"
│ ├── 宿主机端口:9000
│ ├── 容器端口:80
│ └── 访问:http://server-ip:9000
│
├── 注意事项
│ ├── 宿主机端口不能冲突
│ ├── 容器端口必须与 Nginx 配置一致
│ ├── 修改 Nginx 配置后需重启容器
│ └── 端口范围:1-65535
│
└── 常见错误
├── 端口被占用:修改宿主机端口
├── 容器端口错误:检查 Nginx 配置
└── 防火墙拦截:开放对应端口端口映射示例:
yaml
# 示例 1:Nginx 默认端口 80
ports:
- "4080:80" # 访问 http://server-ip:4080
# 示例 2:Nginx 监听 8000
ports:
- "4082:8000" # 访问 http://server-ip:4082
# 示例 3:映射多个端口
ports:
- "4080:80" # HTTP
- "4443:443" # HTTPS2.3 Volume 映射详解
code
Volume 映射详解:
│
├── 概念
│ ├── 将宿主机目录映射到容器内部
│ ├── 容器内修改 → 宿主机同步修改
│ └── 宿主机修改 → 容器内同步修改
│
├── 映射类型
│ ├── 目录映射:/host/path:/container/path
│ ├── 文件映射:/host/file:/container/file
│ └── 匿名卷:/container/path(不推荐)
│
├── 常见映射目录
│ ├── 网站目录
│ │ └── /home/website:/usr/share/nginx/html
│ │
│ ├── Nginx 配置目录
│ │ └── /etc/nginx/conf.d:/etc/nginx/conf.d
│ │
│ ├── Nginx 主配置文件
│ │ └── /etc/nginx/nginx.conf:/etc/nginx/nginx.conf
│ │
│ └── 日志目录
│ └── /var/log/nginx:/var/log/nginx
│
├── 注意事项
│ ├── 宿主机目录必须存在
│ ├── 路径使用绝对路径
│ ├── 容器内路径由镜像决定
│ └── 权限问题:确保读写权限
│
└── 最佳实践
├── 使用数据卷(named volumes)
├── 配置文件单独映射
├── 日志目录单独映射
└── 使用相对路径(docker-compose.yml 所在目录)Volume 映射完整示例:
yaml
# docker-compose-nginx.yml
version: '3'
services:
nginx:
restart: always
image: nginx
container_name: nginx1
environment:
- TZ=Asia/Shanghai
ports:
- "4082:8000" # Nginx 监听 8000
volumes:
# 网站目录映射
- /home/website:/usr/share/nginx/html
# Nginx 配置文件映射
- /etc/nginx/conf.d:/etc/nginx/conf.d
# Nginx 主配置文件映射
- /etc/nginx/nginx.conf:/etc/nginx/nginx.conf
# 日志目录映射
- /var/log/nginx:/var/log/nginx2.4 Nginx 配置文件映射示例
场景:自定义 Nginx 配置
yaml
# docker-compose-nginx.yml
version: '3'
services:
nginx1:
restart: always
image: nginx
container_name: nginx1
environment:
- TZ=Asia/Shanghai
ports:
- "4082:8000" # 注意:容器内监听 8000
volumes:
# 网站目录
- /home/website:/usr/share/nginx/html
# Nginx 配置文件(包含监听 8000)
- /etc/nginx/conf.d:/etc/nginx/conf.d对应的 Nginx 配置文件:
nginx
# /etc/nginx/conf.d/site1.conf
server {
listen 8000; # 监听 8000 端口
server_name site1.com;
location / {
root /usr/share/nginx/html/project-front-vue3;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}重要提示:
code
端口映射与 Nginx 配置关系:
│
├── Docker Compose 端口映射
│ └── ports: "4082:8000"
│ ├── 4082:宿主机端口(外部访问)
│ └── 8000:容器端口(Nginx 监听端口)
│
├── Nginx 配置文件
│ └── listen 8000;
│ └── 必须与容器端口一致
│
├── 访问方式
│ └── http://server-ip:4082
│
└── 流程
├── 浏览器 → http://server-ip:4082
├── Docker → 映射到容器 8000 端口
└── Nginx → 监听 8000 端口,响应请求2.5 方式一完整部署流程
code
方式一完整部署流程:
│
├── 第一步:准备网站文件
│ ├── 构建项目:npm run build
│ ├── 上传文件到宿主机
│ └── 目标路径:/home/website/project-front-vue3
│
├── 第二步:创建 Docker Compose 配置
│ ├── 创建文件:vi /home/nginx/docker-compose.yml
│ ├── 编写配置内容
│ └── 保存退出
│
├── 第三步:启动容器
│ ├── 启动:docker-compose up -d
│ ├── 查看状态:docker ps
│ └── 查看日志:docker logs nginx
│
├── 第四步:测试访问
│ ├── 浏览器访问:http://server-ip:4080
│ ├── 检查页面显示
│ └── 检查静态资源加载
│
└── 第五步:更新部署
├── 上传新的构建文件
├── 无需重启容器(Volume 映射自动生效)
└── 刷新浏览器即可看到更新方式一常用命令:
bash
# 启动容器
docker-compose up -d
# 指定配置文件启动
docker-compose -f docker-compose-nginx.yml up -d
# 查看容器状态
docker ps
# 查看容器日志
docker logs nginx
# 重启容器
docker-compose restart
# 停止容器
docker-compose down
# 进入容器内部
docker exec -it nginx bash三、方式二:构建 Docker 镜像(推荐)
3.1 Dockerfile 最佳实践
多阶段构建 Dockerfile(推荐):
dockerfile
# ==================== 构建阶段 ====================
# 使用 Node.js 作为构建环境
FROM node:18-alpine AS builder
# 设置工作目录
WORKDIR /app
# 配置 npm 镜像源(可选)
RUN npm config set registry https://registry.npmmirror.com
# 安装 pnpm(如果项目使用 pnpm)
RUN npm install -g pnpm
# 复制 package.json 和 lock 文件
COPY package.json pnpm-lock.yaml ./
# 安装依赖
RUN pnpm install --frozen-lockfile
# 复制项目代码
COPY . .
# 构建项目
RUN pnpm run build
# ==================== 生产阶段 ====================
# 使用 Nginx 作为运行环境
FROM nginx:alpine
# 复制构建产物到 Nginx 目录
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制 Nginx 配置文件(可选)
# COPY nginx.conf /etc/nginx/conf.d/default.conf
# 暴露端口
EXPOSE 80
# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]Dockerfile 结构详解:
code
Dockerfile 多阶段构建详解:
│
├── 构建阶段(Build Stage)
│ ├── FROM node:18-alpine AS builder
│ │ ├── 使用 Node.js 18 Alpine 镜像
│ │ ├── Alpine:极简 Linux 环境(体积小)
│ │ └── AS builder:命名此阶段为 builder
│ │
│ ├── WORKDIR /app
│ │ ├── 设置工作目录
│ │ └── 后续操作都在 /app 目录下
│ │
│ ├── RUN npm config set registry
│ │ ├── 配置 npm 镜像源
│ │ └── 加速依赖下载
│ │
│ ├── RUN npm install -g pnpm
│ │ ├── 全局安装 pnpm
│ │ └── 如果使用 npm 则不需要
│ │
│ ├── COPY package.json pnpm-lock.yaml ./
│ │ ├── 复制依赖配置文件
│ │ ├── 优先复制:利用 Docker 缓存
│ │ └── package.json 未变化则不重新安装依赖
│ │
│ ├── RUN pnpm install --frozen-lockfile
│ │ ├── 安装依赖
│ │ ├── --frozen-lockfile:严格按照 lock 文件
│ │ └── 确保依赖版本一致
│ │
│ ├── COPY . .
│ │ ├── 复制所有项目文件
│ │ └── 受 .dockerignore 影响
│ │
│ └── RUN pnpm run build
│ ├── 构建项目
│ ├── 生成 dist 目录
│ └── 这是最终需要的产物
│
├── 生产阶段(Production Stage)
│ ├── FROM nginx:alpine
│ │ ├── 使用 Nginx Alpine 镜像
│ │ ├── Alpine 镜像体积小(~20MB)
│ │ └── 不包含 Node.js 等构建工具
│ │
│ ├── COPY --from=builder /app/dist /usr/share/nginx/html
│ │ ├── 从构建阶段复制产物
│ │ ├── --from=builder:指定源阶段
│ │ ├── /app/dist:构建阶段的产物路径
│ │ └── /usr/share/nginx/html:Nginx 默认静态资源目录
│ │
│ ├── EXPOSE 80
│ │ ├── 声明暴露端口
│ │ ├── 仅为文档说明
│ │ └── 实际映射在 docker run 时指定
│ │
│ └── CMD ["nginx", "-g", "daemon off;"]
│ ├── 启动 Nginx
│ ├── -g "daemon off;":前台运行
│ └── 容器需要前台进程
│
└── 多阶段构建优势
├── 最终镜像不包含 Node.js
├── 不包含 node_modules
├── 不包含源代码
├── 镜像体积小(~20MB)
└── 安全性高 3.2 镜像体积优化策略
code
镜像体积优化策略:
│
├── 1. 使用 Alpine 镜像
│ ├── node:18-alpine(~40MB)
│ ├── nginx:alpine(~20MB)
│ ├── 相比标准镜像减少 80%+
│ └── 缺点:部分包可能不兼容
│
├── 2. 多阶段构建
│ ├── 构建阶段:使用 Node.js 镜像
│ ├── 生产阶段:使用 Nginx 镜像
│ ├── 最终镜像:只包含 Nginx + dist
│ └── 镜像体积:~22MB
│
├── 3. 优化依赖安装
│ ├── 使用 --frozen-lockfile
│ ├── 只安装生产依赖:--production
│ ├── 清理缓存:npm cache clean
│ └── 删除不必要的依赖
│
├── 4. 使用 .dockerignore
│ ├── 忽略 node_modules
│ ├── 忽略 .git
│ ├── 忽略构建产物
│ └── 忽略测试文件
│
└── 5. 减少镜像层数
├── 合并 RUN 命令
├── 使用 && 连接多个命令
└── 清理临时文件镜像体积对比:
| 方式 | 镜像内容 | 体积 | 推荐度 |
|---|---|---|---|
| 单阶段构建 | Node.js + 源码 + node_modules + dist | ~1GB+ | |
| 多阶段构建 | Nginx + dist | ~22MB | |
| Alpine + 多阶段 | Nginx Alpine + dist | ~20MB |
3.3 .dockerignore 配置
.dockerignore 文件:
gitignore
# 依赖目录
node_modules
.pnpm-store
# 构建产物
dist
.output
.next
.nuxt
build
# 日志文件
logs
*.log
npm-debug.log*
pnpm-debug.log*
# 环境配置
.env
.env.local
.env.*.local
# 编辑器
.idea
.vscode
*.swp
*.swo
*~
# Git
.git
.gitignore
# 测试文件
coverage
.nyc_output
**/*.test.js
**/*.spec.js
**/*.test.ts
**/*.spec.ts
# 文档
README.md
CHANGELOG.md
LICENSE
# 其他
.DS_Store
Thumbs.db.dockerignore 作用:
code
.dockerignore 作用详解:
│
├── 概念
│ ├── 类似 .gitignore
│ ├── 控制哪些文件不被复制到镜像
│ └── 减少 COPY . . 时复制的文件
│
├── 作用
│ ├── 减少构建上下文大小
│ ├── 加快构建速度
│ ├── 减小镜像体积
│ └── 提高安全性(不包含敏感文件)
│
├── 必须忽略的文件
│ ├── node_modules(已在镜像中安装)
│ ├── .git(源码控制,不需要)
│ ├── dist(会在镜像中构建)
│ ├── .env(敏感信息,不应打包)
│ └── 测试文件(生产环境不需要)
│
└── 最佳实践
├── 从 .gitignore 复制基础配置
├── 添加 Docker 特定的忽略项
└── 定期审查和更新3.4 构建与运行 Docker 镜像
构建镜像:
bash
# 基础构建
docker build -t frontend:v1.0.0 .
# 详细构建过程
docker build --no-cache -t frontend:v1.0.0 .
# 查看构建的镜像
docker images
# 镜像输出示例
# REPOSITORY TAG IMAGE ID CREATED SIZE
# frontend v1.0.0 abc123def456 10 seconds ago 22MB运行镜像:
bash
# 基础运行
docker run -d --name frontend-app -p 9000:80 frontend:v1.0.0
# 参数详解
# -d:后台运行
# --name frontend-app:容器名称
# -p 9000:80:端口映射(宿主机:容器)
# frontend:v1.0.0:镜像名称:标签
# 查看运行状态
docker ps
# 查看容器日志
docker logs frontend-app
# 进入容器内部
docker exec -it frontend-app sh
# 停止容器
docker stop frontend-app
# 删除容器
docker rm frontend-app
# 删除镜像
docker rmi frontend:v1.0.0构建流程详解:
code
Docker 镜像构建流程:
│
├── 第一步:准备项目文件
│ ├── 确保项目可以正常构建
│ ├── 创建 Dockerfile
│ ├── 创建 .dockerignore
│ └── 检查 package.json
│
├── 第二步:构建镜像
│ ├── docker build -t frontend:v1.0.0 .
│ ├── Docker 读取 Dockerfile
│ ├── 执行构建指令
│ └── 生成镜像
│
├── 第三步:查看镜像
│ ├── docker images
│ ├── 检查镜像大小
│ └── 检查镜像标签
│
├── 第四步:运行容器
│ ├── docker run -d --name app -p 9000:80 frontend:v1.0.0
│ ├── Docker 创建容器
│ ├── 启动容器内的 Nginx
│ └── 映射端口
│
├── 第五步:测试访问
│ ├── 浏览器访问:http://localhost:9000
│ ├── 检查页面显示
│ └── 检查静态资源加载
│
└── 第六步:镜像管理
├── 推送到镜像仓库
├── 版本管理
└── 分发部署3.5 常见问题与解决方案
问题 1:依赖安装失败
code
问题:依赖安装失败
│
├── 现象
│ ├── npm ERR! network request failed
│ ├── pnpm: ERR_PNPM_FETCH_*
│ └── 依赖下载超时
│
├── 原因
│ ├── 国外镜像源访问慢
│ ├── 网络连接问题
│ └── 镜像源配置错误
│
└── 解决方案
├── 配置淘宝镜像源
│ └── RUN npm config set registry https://registry.npmmirror.com
│
├── 使用 pnpm 淘宝源
│ └── RUN pnpm config set registry https://registry.npmmirror.com
│
└── 使用代理(如有)
└── RUN npm config set proxy http://proxy-server:port问题 2:镜像体积过大
code
问题:镜像体积过大
│
├── 现象
│ ├── 镜像大小 > 500MB
│ ├── 构建速度慢
│ └── 推送/拉取耗时长
│
├── 原因
│ ├── 未使用多阶段构建
│ ├── 包含 node_modules
│ ├── 包含源代码
│ └── 使用标准镜像(非 Alpine)
│
└── 解决方案
├── 使用多阶段构建
│ └── FROM node:18-alpine AS builder
│
├── 使用 Alpine 镜像
│ └── FROM nginx:alpine
│
├── 添加 .dockerignore
│ └── 忽略 node_modules、.git 等
│
└── 优化依赖安装
└── RUN pnpm install --production --frozen-lockfile问题 3:构建时依赖缺失
code
问题:构建时依赖缺失
│
├── 现象
│ ├── Module not found: workbox-window
│ ├── Cannot find module 'xxx'
│ └── 构建失败
│
├── 原因
│ ├── 依赖未安装
│ ├── 依赖版本不兼容
│ └── devDependencies 中缺少构建依赖
│
└── 解决方案
├── 安装缺失依赖
│ └── pnpm install -D workbox-window
│
├── 检查 package.json
│ ├── 确保 devDependencies 包含构建工具
│ └── 例如:vite、webpack、typescript 等
│
└── 使用 --frozen-lockfile
└── 确保依赖版本一致问题 4:容器启动后无法访问
code
问题:容器启动后无法访问
│
├── 现象
│ ├── 浏览器无法打开页面
│ ├── 连接被拒绝
│ └── 404 Not Found
│
├── 原因
│ ├── 端口映射错误
│ ├── Nginx 配置错误
│ ├── 静态资源路径错误
│ └── 容器未正常启动
│
└── 解决方案
├── 检查容器状态
│ └── docker ps -a
│
├── 查看容器日志
│ └── docker logs frontend-app
│
├── 检查端口映射
│ └── docker port frontend-app
│
├── 进入容器检查
│ ├── docker exec -it frontend-app sh
│ ├── ls /usr/share/nginx/html
│ └── cat /etc/nginx/conf.d/default.conf
│
└── 检查防火墙
└── 开放对应端口四、Vue3 项目完整容器化实战
4.1 项目文件结构
code
Vue3 项目 Docker 化文件结构:
│
├── project-front-vue3/
│ ├── src/ # 源代码
│ ├── public/ # 静态资源
│ ├── package.json # 依赖配置
│ ├── pnpm-lock.yaml # 依赖锁定文件
│ ├── vite.config.ts # Vite 配置
│ ├── tsconfig.json # TypeScript 配置
│ ├── Dockerfile # Docker 配置文件
│ ├── .dockerignore # Docker 忽略文件
│ ├── docker-compose.yml # Docker Compose 配置(可选)
│ └── nginx.conf # Nginx 配置(可选)
│
└── 注意
├── Dockerfile 和 .dockerignore 必须在项目根目录
├── Dockerfile 文件名区分大小写
└── .dockerignore 以点开头4.2 Dockerfile 完整示例
dockerfile
# ==================== 构建阶段 ====================
# 使用 Node.js 18 Alpine 作为构建环境
FROM node:18-alpine AS builder
# 设置工作目录
WORKDIR /app
# 配置淘宝镜像源(加速下载)
RUN npm config set registry https://registry.npmmirror.com
# 安装 pnpm
RUN npm install -g pnpm
# 配置 pnpm 淘宝源
RUN pnpm config set registry https://registry.npmmirror.com
# 复制依赖配置文件(利用 Docker 缓存)
COPY package.json pnpm-lock.yaml ./
# 安装依赖
RUN pnpm install --frozen-lockfile
# 复制项目代码
COPY . .
# 构建项目
RUN pnpm run build
# ==================== 生产阶段 ====================
# 使用 Nginx Alpine 作为运行环境
FROM nginx:alpine
# 复制构建产物到 Nginx 目录
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制自定义 Nginx 配置(可选)
# COPY nginx.conf /etc/nginx/conf.d/default.conf
# 暴露端口
EXPOSE 80
# 启动 Nginx(前台运行)
CMD ["nginx", "-g", "daemon off;"]4.3 .dockerignore 完整示例
gitignore
# 依赖目录
node_modules
.pnpm-store
# 构建产物
dist
.output
# 日志文件
logs
*.log
npm-debug.log*
pnpm-debug.log*
# 环境配置(敏感信息)
.env
.env.local
.env.*.local
# 编辑器和 IDE
.idea
.vscode
*.swp
*.swo
*~
# Git
.git
.gitignore
# 测试文件
coverage
.nyc_output
**/*.test.js
**/*.spec.js
**/*.test.ts
**/*.spec.ts
cypress
cypress.config.ts
# 文档
README.md
CHANGELOG.md
LICENSE
docs
# Docker 相关
Dockerfile
docker-compose.yml
.dockerignore
# 其他
.DS_Store
Thumbs.db
*.bak
*.tmp4.4 docker-compose.yml 完整示例
yaml
# docker-compose.yml
version: '3.8'
services:
frontend:
# 从当前目录构建镜像
build:
context: .
dockerfile: Dockerfile
# 镜像名称和标签
image: frontend:v1.0.0
# 容器名称
container_name: frontend-app
# 重启策略
restart: always
# 环境变量
environment:
- TZ=Asia/Shanghai
# 端口映射
ports:
- "9000:80"
# 健康检查
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# 资源限制
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M4.5 自定义 Nginx 配置(可选)
nginx.conf(Vue SPA 路由支持):
nginx
# nginx.conf
server {
listen 80;
server_name localhost;
# 静态资源目录
root /usr/share/nginx/html;
index index.html index.htm;
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 1000;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Vue SPA 路由支持
location / {
try_files $uri $uri/ /index.html;
}
# API 代理(如需要)
# location /api/ {
# proxy_pass http://backend:3000/;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# }
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}在 Dockerfile 中使用自定义 Nginx 配置:
dockerfile
# 复制自定义 Nginx 配置
COPY nginx.conf /etc/nginx/conf.d/default.conf4.6 完整部署流程
code
Vue3 项目完整部署流程:
│
├── 本地准备阶段
│ ├── 1. 确保项目可以正常构建
│ │ └── pnpm run build
│ │
│ ├── 2. 创建 Dockerfile
│ │ └── 编写多阶段构建配置
│ │
│ ├── 3. 创建 .dockerignore
│ │ └── 配置忽略文件
│ │
│ ├── 4. 创建 docker-compose.yml(可选)
│ │ └── 配置 Docker Compose
│ │
│ └── 5. 创建 nginx.conf(可选)
│ └── 配置 Nginx
│
├── 构建镜像阶段
│ ├── 1. 构建镜像
│ │ └── docker build -t frontend:v1.0.0 .
│ │
│ ├── 2. 查看镜像
│ │ └── docker images
│ │
│ └── 3. 测试镜像
│ └── docker run -d --name test -p 9000:80 frontend:v1.0.0
│
├── 本地测试阶段
│ ├── 1. 浏览器访问
│ │ └── http://localhost:9000
│ │
│ ├── 2. 检查页面显示
│ │
│ ├── 3. 检查静态资源加载
│ │
│ └── 4. 停止并删除测试容器
│ ├── docker stop test
│ └── docker rm test
│
├── 推送镜像阶段(可选)
│ ├── 1. 登录镜像仓库
│ │ └── docker login
│ │
│ ├── 2. 标记镜像
│ │ └── docker tag frontend:v1.0.0 username/frontend:v1.0.0
│ │
│ └── 3. 推送镜像
│ └── docker push username/frontend:v1.0.0
│
└── 服务器部署阶段
├── 1. 拉取镜像(或上传)
│ └── docker pull username/frontend:v1.0.0
│
├── 2. 创建 docker-compose.yml
│
├── 3. 启动服务
│ └── docker-compose up -d
│
├── 4. 查看状态
│ └── docker-compose ps
│
└── 5. 测试访问
└── http://server-ip:90004.7 部署脚本示例
deploy.sh(自动化部署脚本):
bash
#!/bin/bash
# 部署脚本
set -e
# 配置变量
IMAGE_NAME="frontend"
IMAGE_TAG="v1.0.0"
CONTAINER_NAME="frontend-app"
PORT="9000"
echo "===== 开始部署 ====="
# 停止并删除旧容器
echo "停止旧容器..."
docker stop $CONTAINER_NAME 2>/dev/null || true
docker rm $CONTAINER_NAME 2>/dev/null || true
# 构建新镜像
echo "构建新镜像..."
docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .
# 运行新容器
echo "运行新容器..."
docker run -d \
--name $CONTAINER_NAME \
-p ${PORT}:80 \
--restart always \
-e TZ=Asia/Shanghai \
${IMAGE_NAME}:${IMAGE_TAG}
# 查看状态
echo "查看容器状态..."
docker ps | grep $CONTAINER_NAME
# 清理旧镜像
echo "清理未使用的镜像..."
docker image prune -f
echo "===== 部署完成 ====="
echo "访问地址: http://localhost:${PORT}"使用方式:
bash
# 添加执行权限
chmod +x deploy.sh
# 执行部署
./deploy.sh五、两种部署方式对比总结
5.1 方式对比表
| 维度 | 方式一:Volume 映射 | 方式二:构建镜像 |
|---|---|---|
| 配置复杂度 | 简单 | 中等 |
| 环境一致性 | 一般 | 极好 |
| 部署速度 | 快 | 中等 |
| 迁移便利性 | 需要宿主机目录 | 一键迁移 |
| 版本管理 | 不方便 | 清晰 |
| CI/CD 友好 | 一般 | 极好 |
| 调试便利性 | 方便 | 需进入容器 |
| 安全性 | 一般 | 高 |
| 推荐场景 | 开发、测试环境 | 生产环境 |
5.2 选择建议
code
部署方式选择建议:
│
├── 推荐使用方式二(构建镜像)的场景
│ ├── 生产环境
│ ├── 多环境部署
│ ├── CI/CD 流水线
│ ├── 微服务架构
│ ├── 需要版本管理
│ └── 大型项目
│
├── 可以使用方式一(Volume 映射)的场景
│ ├── 开发环境
│ ├── 快速测试
│ ├── 频繁修改
│ ├── 临时部署
│ └── 学习 Docker
│
└── 最佳实践
├── 开发环境:使用方式一(方便调试)
├── 测试环境:使用方式二(接近生产)
└── 生产环境:使用方式二(稳定可靠)六、最佳实践总结
6.1 Dockerfile 最佳实践
code
Dockerfile 最佳实践:
│
├── 1. 使用多阶段构建
│ ├── 构建阶段:Node.js 环境
│ ├── 生产阶段:Nginx 环境
│ └── 减小镜像体积
│
├── 2. 使用 Alpine 镜像
│ ├── node:18-alpine
│ ├── nginx:alpine
│ └── 体积小、安全
│
├── 3. 优化构建缓存
│ ├── 优先复制 package.json
│ ├── 后复制源代码
│ └── 利用 Docker 缓存机制
│
├── 4. 使用 .dockerignore
│ ├── 忽略 node_modules
│ ├── 忽略 .git
│ └── 忽略构建产物
│
├── 5. 配置镜像源
│ ├── 使用淘宝镜像源
│ ├── 加速依赖下载
│ └── 提高构建速度
│
├── 6. 固定依赖版本
│ ├── 使用 --frozen-lockfile
│ ├── 确保版本一致
│ └── 避免依赖冲突
│
├── 7. 减少镜像层数
│ ├── 合并 RUN 命令
│ ├── 使用 && 连接
│ └── 清理临时文件
│
└── 8. 添加元数据
├── LABEL maintainer
├── LABEL version
└── LABEL description6.2 Docker Compose 最佳实践
code
Docker Compose 最佳实践:
│
├── 1. 使用版本 3.x
│ ├── version: '3.8'
│ └── 支持更多功能
│
├── 2. 明确指定镜像版本
│ ├── image: nginx:1.25-alpine
│ ├── 不使用 latest 标签
│ └── 确保版本一致
│
├── 3. 配置重启策略
│ ├── restart: always
│ └── 自动重启服务
│
├── 4. 设置资源限制
│ ├── CPU 限制
│ ├── 内存限制
│ └── 防止资源耗尽
│
├── 5. 配置健康检查
│ ├── healthcheck
│ ├── 监控服务状态
│ └── 自动重启
│
├── 6. 使用环境变量文件
│ ├── env_file
│ ├── .env 文件
│ └── 敏感信息管理
│
└── 7. 网络配置
├── 自定义网络
├── 服务间通信
└── 隔离性6.3 镜像管理最佳实践
code
镜像管理最佳实践:
│
├── 1. 版本管理
│ ├── 使用语义化版本:v1.0.0
│ ├── latest 标签指向最新稳定版
│ ├── 保留历史版本
│ └── 及时清理过期版本
│
├── 2. 镜像仓库
│ ├── 使用私有仓库(生产环境)
│ ├── Docker Hub(开源项目)
│ ├── 阿里云容器镜像服务
│ └── Harbor(企业级)
│
├── 3. 镜像安全
│ ├── 定期扫描漏洞
│ ├── 使用可信镜像
│ ├── 最小化镜像内容
│ └── 不包含敏感信息
│
├── 4. 镜像优化
│ ├── 使用 Alpine 镜像
│ ├── 多阶段构建
│ ├── 清理缓存
│ └── 压缩镜像
│
└── 5. 镜像分发
├── 推送到镜像仓库
├── 使用 CDN 加速
├── 区域镜像复制
└── 镜像签名七、命令速查表
7.1 Docker 常用命令速查
| 命令 | 说明 |
|---|---|
| 镜像管理 | |
docker build -t name:tag . | 构建镜像 |
docker images | 查看本地镜像 |
docker rmi name:tag | 删除镜像 |
docker tag old new | 标记镜像 |
docker push name:tag | 推送镜像到仓库 |
docker pull name:tag | 从仓库拉取镜像 |
docker image prune -f | 清理未使用的镜像 |
| 容器管理 | |
docker run -d --name app -p 9000:80 image:tag | 运行容器 |
docker ps | 查看运行中的容器 |
docker ps -a | 查看所有容器 |
docker stop container | 停止容器 |
docker start container | 启动容器 |
docker restart container | 重启容器 |
docker rm container | 删除容器 |
docker logs container | 查看容器日志 |
docker exec -it container sh | 进入容器 |
docker cp local container:path | 复制文件到容器 |
| 系统管理 | |
docker info | 查看 Docker 信息 |
docker system df | 查看磁盘使用 |
docker system prune -f | 清理未使用资源 |
7.2 Docker Compose 常用命令速查
| 命令 | 说明 |
|---|---|
docker-compose up -d | 后台启动所有服务 |
docker-compose -f file.yml up -d | 使用指定配置文件启动 |
docker-compose down | 停止并删除所有容器 |
docker-compose ps | 查看服务状态 |
docker-compose logs | 查看所有服务日志 |
docker-compose logs service | 查看指定服务日志 |
docker-compose restart | 重启所有服务 |
docker-compose restart service | 重启指定服务 |
docker-compose stop | 停止所有服务 |
docker-compose start | 启动所有服务 |
docker-compose build | 构建所有服务的镜像 |
docker-compose pull | 拉取所有服务的镜像 |
docker-compose exec service sh | 进入指定服务的容器 |
7.3 Dockerfile 常用指令速查
| 指令 | 说明 | 示例 |
|---|---|---|
FROM | 基础镜像 | FROM node:18-alpine |
WORKDIR | 工作目录 | WORKDIR /app |
COPY | 复制文件 | COPY . . |
ADD | 添加文件(支持 URL) | ADD file.tar.gz /tmp/ |
RUN | 运行命令 | RUN npm install |
CMD | 容器启动命令 | CMD ["nginx", "-g", "daemon off;"] |
ENTRYPOINT | 入口点 | ENTRYPOINT ["node", "app.js"] |
ENV | 环境变量 | ENV NODE_ENV production |
EXPOSE | 暴露端口 | EXPOSE 80 |
VOLUME | 数据卷 | VOLUME /data |
USER | 用户 | USER node |
LABEL | 元数据 | LABEL version="1.0" |
ARG | 构建参数 | ARG NODE_ENV |
八、学习要点总结
8.1 核心知识点
code
Docker 容器化部署核心知识点:
│
├── 基础概念
│ ├── Docker 镜像(Image)
│ ├── Docker 容器(Container)
│ ├── Docker 仓库(Registry)
│ └── Docker Compose
│
├── 部署方式
│ ├── 方式一:Volume 映射
│ │ ├── 简单灵活
│ │ ├── 适合开发测试
│ │ └── 需要宿主机目录
│ │
│ └── 方式二:构建镜像(推荐)
│ ├── 环境独立
│ ├── 易于迁移
│ └── 适合生产环境
│
├── Dockerfile 编写
│ ├── 多阶段构建
│ ├── Alpine 镜像
│ ├── .dockerignore
│ ├── 构建缓存优化
│ └── 镜像体积优化
│
├── Docker Compose 配置
│ ├── version
│ ├── services
│ ├── ports
│ ├── volumes
│ └── environment
│
└── 最佳实践
├── 使用多阶段构建
├── 使用 Alpine 镜像
├── 配置 .dockerignore
├── 固定依赖版本
└── 镜像版本管理8.2 重要程度标注
| 知识点 | 重要程度 | 必须掌握 |
|---|---|---|
| Docker 基础概念 | ||
| 多阶段构建 | ||
| Dockerfile 编写 | ||
| .dockerignore 配置 | ||
| 镜像体积优化 | ||
| Docker Compose 配置 | ||
| 端口映射原理 | ||
| Volume 映射 | ||
| 镜像版本管理 | ||
| 镜像仓库使用 |
8.3 学习路径规划
code
学习路径规划:
│
├── 第一阶段:理解概念(1 天)
│ ├── Docker 基础概念
│ ├── 镜像与容器
│ ├── Docker Compose
│ └── 容器化优势
│
├── 第二阶段:实践操作(2-3 天)
│ ├── 编写 Dockerfile
│ ├── 构建镜像
│ ├── 运行容器
│ ├── Docker Compose 配置
│ └── 完整项目容器化
│
├── 第三阶段:深入应用(持续)
│ ├── 镜像优化
│ ├── 多阶段构建进阶
│ ├── CI/CD 集成
│ ├── 镜像仓库管理
│ └── 生产环境最佳实践
│
└── 推荐资源
├── Docker 官方文档
├── Docker Hub
├── Vue.js 官方部署指南
└── 实际项目练习九、扩展阅读
9.1 CI/CD 自动化部署
code
CI/CD 自动化部署流程:
│
├── 1. 代码提交
│ └── Git Push → 触发 CI/CD
│
├── 2. 自动构建
│ ├── 安装依赖
│ ├── 运行测试
│ ├── 构建项目
│ └── 构建 Docker 镜像
│
├── 3. 镜像推送
│ ├── 推送到镜像仓库
│ └── 打上版本标签
│
├── 4. 自动部署
│ ├── 拉取新镜像
│ ├── 停止旧容器
│ └── 启动新容器
│
└── 5. 常用工具
├── GitHub Actions
├── GitLab CI/CD
├── Jenkins
└── Travis CI9.2 Docker 镜像仓库
code
Docker 镜像仓库选择:
│
├── Docker Hub(官方)
│ ├── 免费:公开仓库
│ ├── 付费:私有仓库
│ ├── 自动构建
│ └── 适合开源项目
│
├── 阿里云容器镜像服务
│ ├── 国内访问快
│ ├── 免费额度
│ ├── 安全扫描
│ └── 适合国内项目
│
├── 腾讯云容器镜像服务
│ ├── 国内访问快
│ ├── 免费额度
│ ├── 安全扫描
│ └── 适合国内项目
│
└── Harbor(企业级)
├── 私有部署
├── 完整功能
├── 企业级管理
└── 适合大型企业 9.3 Docker 网络与安全
code
Docker 网络与安全:
│
├── 网络模式
│ ├── bridge(默认)
│ ├── host(主机模式)
│ ├── none(无网络)
│ └── 自定义网络
│
├── 安全最佳实践
│ ├── 使用官方镜像
│ ├── 定期更新镜像
│ ├── 不以 root 运行
│ ├── 扫描镜像漏洞
│ └── 限制容器资源
│
└── 日志与监控
├── 集中日志管理
├── 容器监控
├── 性能分析
└── 告警机制十、完整代码清单
10.1 Dockerfile 完整代码
dockerfile
# ==================== 构建阶段 ====================
FROM node:18-alpine AS builder
WORKDIR /app
# 配置镜像源
RUN npm config set registry https://registry.npmmirror.com && \
npm install -g pnpm && \
pnpm config set registry https://registry.npmmirror.com
# 复制依赖文件
COPY package.json pnpm-lock.yaml ./
# 安装依赖
RUN pnpm install --frozen-lockfile
# 复制项目代码
COPY . .
# 构建项目
RUN pnpm run build
# ==================== 生产阶段 ====================
FROM nginx:alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制 Nginx 配置(可选)
# COPY nginx.conf /etc/nginx/conf.d/default.conf
# 暴露端口
EXPOSE 80
# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]10.2 docker-compose.yml 完整代码
yaml
version: '3.8'
services:
frontend:
build:
context: .
dockerfile: Dockerfile
image: frontend:v1.0.0
container_name: frontend-app
restart: always
environment:
- TZ=Asia/Shanghai
ports:
- "9000:80"
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M10.3 nginx.conf 完整代码
nginx
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 1000;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Vue SPA 路由支持
location / {
try_files $uri $uri/ /index.html;
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}10.4 .dockerignore 完整代码
gitignore
# 依赖
node_modules
.pnpm-store
# 构建
dist
.output
# 日志
logs
*.log
# 环境配置
.env
.env.local
.env.*.local
# 编辑器
.idea
.vscode
# Git
.git
.gitignore
# 测试
coverage
**/*.test.js
**/*.spec.ts
# Docker
Dockerfile
docker-compose.yml
.dockerignore
# 其他
.DS_Store
README.md10.5 deploy.sh 完整代码
bash
#!/bin/bash
set -e
# 配置
IMAGE_NAME="frontend"
IMAGE_TAG="v1.0.0"
CONTAINER_NAME="frontend-app"
PORT="9000"
echo "===== 开始部署 ====="
# 停止旧容器
echo "停止旧容器..."
docker stop $CONTAINER_NAME 2>/dev/null || true
docker rm $CONTAINER_NAME 2>/dev/null || true
# 构建镜像
echo "构建镜像..."
docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .
# 运行容器
echo "运行容器..."
docker run -d \
--name $CONTAINER_NAME \
-p ${PORT}:80 \
--restart always \
-e TZ=Asia/Shanghai \
${IMAGE_NAME}:${IMAGE_TAG}
# 查看状态
docker ps | grep $CONTAINER_NAME
# 清理
docker image prune -f
echo "===== 部署完成 ====="
echo "访问: http://localhost:${PORT}"重要提示:Docker 容器化部署是现代前端工程化的核心技能,掌握 Dockerfile 编写、多阶段构建、镜像优化、Docker Compose 配置,对实际项目部署非常重要!推荐使用多阶段构建 + Alpine 镜像,确保镜像体积小、安全性高、环境一致!
下节预告:Docker 容器化部署后端项目,深入学习 NestJS/Nuxt.js 容器化、数据库容器、多容器编排、Docker 网络配置等高级应用!
笔记已按照您的格式规范整理完成,可直接用于学习复习!