Docker 生产环境部署指南
本指南介绍如何使用 Docker 和 Docker Compose 将 VUP 项目部署到生产环境。此部署方案适用于完整的全栈应用(API + 前端 + 数据库),针对 DAU ≤ 5000 的应用进行了优化。
什么是 Docker 部署
Docker 部署提供:
- 容器化 - 每个服务都有独立的环境
- 易于更新 - 通过替换文件并重启即可更新,无需重建镜像
- 资源管理 - CPU 和内存限制,防止资源耗尽
- 服务编排 - 使用单个命令管理多个服务(数据库、API、前端、nginx)
- 卷映射 - 直接文件映射,便于更新而无需重建
前置要求
开始之前,请确保您已安装:
- Docker >= 20.10
- Docker Compose >= 2.0
- 服务器 至少 2GB RAM 和 2 CPU 核心
- 域名(可选,用于 HTTPS)
推荐的部署目录
对于生产环境部署,建议使用标准的 Linux 目录结构:
推荐路径: /opt/vup 或 /opt/vup-cli
这遵循 Linux FHS(文件系统层次结构标准)约定,其中 /opt 用于可选的应用软件包。
设置部署目录
# 创建部署目录
sudo mkdir -p /opt/vup
sudo chown $USER:$USER /opt/vup
# 将 deploy 目录复制到推荐位置
cp -r /path/to/project-vue/deploy/* /opt/vup/
# 或者克隆/复制整个 deploy 目录
cd /opt/vup目录结构
设置完成后,您的部署目录应如下所示:
/opt/vup/
├── docker-compose.yml
├── .env
├── builds/
├── nginx/
├── scripts/
├── data/
├── logs/
└── backups/注意: 本指南中的所有路径都假设部署在
/opt/vup。如果您使用不同的目录,请相应调整路径。
快速开始
1. 设置部署目录
# 创建并进入部署目录
sudo mkdir -p /opt/vup
sudo chown $USER:$USER /opt/vup
cd /opt/vup
# 从项目复制 deploy 目录
cp -r /path/to/project-vue/deploy/* /opt/vup/2. 准备环境变量
在部署目录创建 .env 文件:
cd /opt/vup
cp .env.example .env编辑 .env 文件,配置您的设置:
# 数据库配置
MYSQL_DATABASE=vup_db
MYSQL_USER=vup_user
MYSQL_PASSWORD=your_secure_password
MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_PORT=3306
# API 配置
CORS_ORIGIN=https://yourdomain.com
JWT_SECRET=your_jwt_secret_key
JWT_EXPIRES_IN=7d
JWT_REFRESH_EXPIRES_IN=30d
UPLOAD_MAX_FILE_SIZE=1073741824
UPLOAD_BASE_URL=https://yourdomain.com/uploads
# 前端配置
API_BASE_URL=https://yourdomain.com/api
APP_BASE_URL=https://yourdomain.com
# 端口配置
HTTP_PORT=80
HTTPS_PORT=4433. 构建应用
构建您的 API 和 Admin 应用:
# 构建 API
cd apps/nest-template
pnpm build
# 构建 Admin (Nuxt)
cd apps/nuxt-template
pnpm build4. 复制构建产物
将构建产物复制到部署目录:
# 复制 API 构建产物
cp -r /path/to/project-vue/apps/nest-template/.output /opt/vup/builds/api
# 复制 Admin 构建产物
cp -r /path/to/project-vue/apps/nuxt-template/.output /opt/vup/builds/admin5. 启动服务
cd /opt/vup
# 启动所有服务
docker compose up -d
# 查看日志
docker compose logs -f
# 检查服务状态
docker compose ps6. 运行数据库迁移
# 运行迁移
docker compose run --rm migration服务概览
MariaDB 数据库
- 容器:
vup-mariadb - 镜像:
mariadb:11.3 - 端口:
3306(可通过MYSQL_PORT配置) - 数据卷:
./data/mariadb - 备份卷:
./backups/mariadb - 资源限制: 0.8 CPU, 1GB RAM
API 服务
- 容器:
vup-api - 镜像:
node:20-alpine - 端口:
9310(内部) - 构建目录:
./builds/api - 资源限制: 0.6 CPU, 512MB RAM
Admin 前端服务
- 容器:
vup-admin - 镜像:
node:20-alpine - 端口:
3000(内部,Nuxt SSR) - 构建目录:
./builds/admin - 资源限制: 0.2 CPU, 256MB RAM
Nginx 反向代理
- 容器:
vup-nginx - 镜像:
nginx:alpine - 端口:
80(HTTP),443(HTTPS) - 资源限制: 0.2 CPU, 128MB RAM
迁移服务
- 容器:
migration(一次性使用) - 镜像:
node:20-alpine - Profile:
migration(不会自动启动)
配置说明
Docker Compose 配置
docker-compose.yml 文件使用卷映射以便于更新:
- 优势: 通过替换文件并重启即可更新,无需重建镜像
- 适用场景: DAU ≤ 5000
- 更新流程: 替换构建文件 → 重启服务
Nginx 配置
Nginx 作为反向代理,具有以下路由:
/api/→http://api:9310/api/- API 服务/admin/→http://admin:3000/- Admin 前端服务/uploads/→ 静态文件服务(从卷挂载)/→ 重定向到/admin//health→ 健康检查端点
功能特性
- 反向代理 - API 和 Admin 服务通过反向代理访问
- 静态文件服务 - 上传文件通过 Nginx 直接提供
- 文件上传支持 - 最大上传大小 1GB
- Gzip 压缩 - 启用 Gzip 压缩提升性能
- 缓存控制 - 上传文件缓存 30 天
- CORS 支持 - 上传文件支持跨域访问
测试 Nginx 配置
# 测试配置文件语法
docker compose exec nginx nginx -t
# 重新加载配置(不中断服务)
docker compose exec nginx nginx -s reload
# 查看日志
docker compose exec nginx tail -f /var/log/nginx/access.log
docker compose exec nginx tail -f /var/log/nginx/error.logHTTPS 配置(可选)
如果需要启用 HTTPS:
将 SSL 证书文件放到
nginx/ssl/目录:cert.pem- SSL 证书key.pem- SSL 私钥
取消注释
nginx/conf.d/default.conf中的 HTTPS server 块修改
server_name为实际域名重启 nginx:
docker compose restart nginx注意: 生产环境建议使用 Let's Encrypt 免费证书。
部署脚本
deploy/scripts/ 目录包含维护工具脚本:
backup.sh - 数据库备份
备份 MariaDB 数据库和上传文件,自动清理旧备份(保留 7 天)。
./scripts/backup.sh定时任务配置(每日凌晨 2:00):
# 假设部署在 /opt/vup
0 2 * * * /opt/vup/scripts/backup.sh >> /opt/vup/logs/backup.log 2>&1cleanup.sh - 清理脚本
清理旧日志(保留 30 天)、旧备份(保留 7 天)和 Docker 未使用的资源。检查磁盘使用率。
./scripts/cleanup.sh定时任务配置(每日凌晨 3:00):
# 假设部署在 /opt/vup
0 3 * * * /opt/vup/scripts/cleanup.sh >> /opt/vup/logs/cleanup.log 2>&1monitor.sh - 监控脚本
显示服务状态、资源使用情况、磁盘和内存使用、健康检查和告警。
./scripts/monitor.sh定时任务配置(每小时):
# 假设部署在 /opt/vup
0 * * * * /opt/vup/scripts/monitor.sh >> /opt/vup/logs/monitor.log 2>&1restore.sh - 数据库恢复
从备份文件恢复数据库。恢复前自动创建临时备份。
# 查看备份列表
ls -lh backups/mariadb/
# 恢复指定备份
./scripts/restore.sh backups/mariadb/backup_20240101_020000.sql.gz警告: 恢复操作会覆盖当前数据库。恢复前会自动创建临时备份。
设置定时任务
创建设置脚本(/opt/vup/scripts/setup-cron.sh):
#!/bin/bash
# 假设部署在 /opt/vup
DEPLOY_DIR="/opt/vup"
# 备份任务(每日凌晨 2:00)
echo "0 2 * * * ${DEPLOY_DIR}/scripts/backup.sh >> ${DEPLOY_DIR}/logs/backup.log 2>&1" | crontab -
# 清理任务(每日凌晨 3:00)
echo "0 3 * * * ${DEPLOY_DIR}/scripts/cleanup.sh >> ${DEPLOY_DIR}/logs/cleanup.log 2>&1" | crontab -
# 监控任务(每小时)
echo "0 * * * * ${DEPLOY_DIR}/scripts/monitor.sh >> ${DEPLOY_DIR}/logs/monitor.log 2>&1" | crontab -
echo "定时任务已配置"使其可执行:
chmod +x /opt/vup/scripts/setup-cron.sh
/opt/vup/scripts/setup-cron.sh确保脚本有执行权限:
chmod +x scripts/*.sh日常运维
查看日志
# 查看所有服务日志
docker compose logs -f
# 查看特定服务日志
docker compose logs -f api
docker compose logs -f admin
docker compose logs -f nginx
docker compose logs -f mariadb
# 查看本地日志文件
tail -f logs/api/app.log
tail -f logs/admin/app.log
tail -f nginx/logs/access.log
tail -f nginx/logs/error.log重启服务
# 重启所有服务
docker compose restart
# 重启特定服务
docker compose restart api
docker compose restart admin
docker compose restart nginx
# 停止所有服务
docker compose stop
# 启动所有服务
docker compose start健康检查
# 检查服务状态
docker compose ps
# 检查 API 健康
curl http://localhost/api/health
# 检查 Admin 健康
curl http://localhost/admin/
# 检查数据库连接
docker compose exec mariadb mysqladmin ping -h localhost更新应用
- 构建新版本:
# 构建 API
cd apps/nest-template
pnpm build
# 构建 Admin
cd apps/nuxt-template
pnpm build- 复制构建产物:
# 备份当前版本(可选)
cp -r /opt/vup/builds/api /opt/vup/builds/api.backup
cp -r /opt/vup/builds/admin /opt/vup/builds/admin.backup
# 复制新构建
cp -r /path/to/project-vue/apps/nest-template/.output /opt/vup/builds/api
cp -r /path/to/project-vue/apps/nuxt-template/.output /opt/vup/builds/admin- 重启服务:
cd /opt/vup
docker compose restart api admin故障排查
502 Bad Gateway
- 检查 API 或 Admin 服务是否运行:bash
docker compose ps - 检查服务日志:bash
docker compose logs api docker compose logs admin - 验证 nginx 配置中的服务名称(
api、admin) - 验证端口(API: 9310, Admin: 3000)
403 Forbidden
- 检查文件权限:bash
ls -la /opt/vup/data/uploads - 验证
uploads目录是否存在 - 检查 nginx 配置
413 Request Entity Too Large
- 检查 nginx 配置中的
client_max_body_size - 验证 API 服务的
UPLOAD_MAX_FILE_SIZE环境变量
数据库连接问题
- 检查数据库容器状态:bash
docker compose ps mariadb - 检查数据库日志:bash
docker compose logs mariadb - 验证环境变量:bash
docker compose exec api env | grep MYSQL
服务无法启动
- 检查资源限制(CPU/内存)
- 检查磁盘空间:bash
df -h - 检查 Docker 日志:bash
docker compose logs
脚本执行问题
- 检查脚本权限:bash
ls -l scripts/ chmod +x scripts/*.sh - 手动测试脚本:bash
./scripts/backup.sh
最佳实践
资源管理
- 定期监控资源使用:bash
docker stats - 根据实际使用情况调整
docker-compose.yml中的资源限制 - 设置适当的 CPU 和内存限制,防止资源耗尽
备份策略
- 每日备份: 配置定时任务进行每日数据库备份
- 备份保留: 至少保留 7 天的备份
- 测试恢复: 定期测试备份恢复
- 异地备份: 在单独位置存储备份
监控
- 使用
monitor.sh设置每小时监控 - 监控磁盘使用,防止磁盘满
- 设置服务故障告警
- 监控资源使用趋势
安全
- 为数据库使用强密码
- 保持 Docker 和镜像更新
- 生产环境使用 HTTPS
- 限制数据库端口访问(使用防火墙)
- 定期审查和更新环境变量
性能优化
- 在 Nginx 中启用 Gzip 压缩
- 配置适当的缓存头
- 监控和优化数据库查询
- 对静态资源使用 CDN(如适用)
目录结构
推荐的部署目录结构(/opt/vup):
/opt/vup/
├── docker-compose.yml # Docker Compose 配置
├── .env # 环境变量(不在 git 中)
├── builds/ # 构建产物
│ ├── api/ # API 构建产物
│ └── admin/ # Admin 构建产物
├── nginx/ # Nginx 配置
│ ├── nginx.conf # Nginx 主配置
│ ├── conf.d/ # 站点配置
│ │ └── default.conf # 默认站点配置
│ ├── ssl/ # SSL 证书(可选)
│ └── logs/ # Nginx 日志
├── scripts/ # 部署脚本
│ ├── backup.sh # 数据库备份
│ ├── cleanup.sh # 清理脚本
│ ├── monitor.sh # 监控脚本
│ ├── restore.sh # 数据库恢复
│ └── setup-cron.sh # 定时任务设置脚本
├── data/ # 数据卷
│ ├── mariadb/ # 数据库数据
│ └── uploads/ # 上传文件
├── logs/ # 应用日志
│ ├── api/ # API 日志
│ ├── admin/ # Admin 日志
│ ├── backup.log # 备份脚本日志
│ ├── cleanup.log # 清理脚本日志
│ └── monitor.log # 监控脚本日志
└── backups/ # 备份文件
├── mariadb/ # 数据库备份
└── api/ # API 备份注意: 如果您部署到不同的目录,请相应调整脚本和定时任务中的所有路径。