中科兴皖 Docker 部署说明
适用对象:甲方运维人员
部署方式:预构建应用镜像 + compose(交付包不含前后端源码;基础镜像 MySQL/Redis/MinIO 由甲方联网拉取)
对外端口:8112
1. 环境要求
| 项 | 要求 |
|---|---|
| 操作系统 | Linux x86_64(推荐 Ubuntu 22.04 / CentOS 7+) |
| Docker | ≥ 24.0 |
| Docker Compose | v2(docker compose 子命令) |
| 网络 | 可访问 Docker Hub 或已配置国内镜像加速 |
| 硬件 | 建议 4 核 CPU、8 GB 内存、磁盘 ≥ 50 GB |
| 端口 | 宿主机 8112 未被占用 |
验证:
docker --version
docker compose version
docker info | grep -A2 "Registry Mirrors" # 建议已配置国内加速
1.1 Docker 镜像加速(国内强烈建议)
要配。 与 pip / npm 镜像不是一回事:
| 类型 | 作用 | 本项目中谁需要 |
|---|---|---|
| Docker Registry 镜像 | 加速 docker pull / 构建时拉 python:3.9-slim 等 |
发版方打包 + 甲方首次 compose up |
| PyPI / npm 镜像 | 构建镜像时 pip install、pnpm install |
仅发版方打包(已写在 Dockerfile 里) |
甲方 docker load 只导入你们提供的 zkxw-backend / zkxw-web;首次启动仍会 pull 例如:
mysql:5.7.36、redis:7-alpine、minio/minio、minio/mc
发版方在 Mac 上 docker build 时也要拉 python:3.9-slim、node:20-alpine、nginx:1.27-alpine。
macOS(Docker Desktop)
Settings → Docker Engine,在 JSON 中增加(示例,任选可用加速地址):
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.m.daocloud.io"
]
}
保存后 Apply & Restart。你本机若 docker info 已显示 Registry Mirrors: https://docker.1ms.run/,说明已配置,无需重复。
Linux 云主机(发版 / 甲方)
编辑 /etc/docker/daemon.json:
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://docker.m.daocloud.io"
]
}
然后:
sudo systemctl daemon-reload
sudo systemctl restart docker
说明
- 镜像加速由 Docker 守护进程配置,写进 Dockerfile 无效。
- 公司若已有 阿里云 ACR 个人版加速地址,优先用官方提供的专属 URL。
- 应用镜像
zkxw-*来自交付包docker load,不经过 Hub 拉取。 - 若
docker.1ms.run拉取node/nginx报 not found,前端构建 Dockerfile 已默认改用docker.m.daocloud.io/library/...;或在 Docker Engine 中把 DaoCloud 放在registry-mirrors第一条。
2. 交付方打包(我方,含源码仓库)
在己方开发机或 CI(有完整 Git 仓库)执行:
./scripts/package-docker-deploy.sh # 默认日期版本
./scripts/package-docker-deploy.sh v1.0.0 # 指定版本号
package-docker-deploy.sh 固定构建 linux/amd64 镜像(适配甲方 Linux x86 云主机)。仅在对方确认为 ARM 云主机时,发版前改脚本中的 DOCKER_PLATFORM 为 linux/arm64。
脚本会:
- 本地
docker build生成zkxw-backend:<版本>、zkxw-web:<版本> docker save导出为images/zkxw-app-images.tar- 打包 compose、
.env.example、docs/sql/zkxw.sql(不含backend/、web-admin/源码)
产物:dist/zkxw-docker-deploy-<版本>.tar.gz
仅重新构建镜像、不重新打交付包时:
./scripts/build-docker-images.sh v1.0.0
发版方在仓库内从源码本地调试构建:
cd deploy/docker
docker compose -f docker-compose.yml -f docker-compose.build.yml build
docker compose up -d
交付前自检:
tar -xzf dist/zkxw-docker-deploy-*.tar.gz -C /tmp
cd /tmp/zkxw-docker-deploy-*
docker load -i images/zkxw-app-images.tar
cd deploy/docker && cp .env.example .env
docker compose up -d
curl -s http://127.0.0.1:8112/health
3. 交付包目录说明(甲方收到的内容)
zkxw-docker-deploy-<版本>/
├── images/
│ └── zkxw-app-images.tar # 预构建前后端镜像(无源码)
├── deploy/docker/
│ ├── docker-compose.yml
│ ├── .env.example # 含 ZKXW_*_IMAGE 版本号
│ └── mysql/init/
├── docs/sql/zkxw.sql # 首次部署自动建库用
├── 部署说明.md
├── 部署指导手册.html # 客户安装手册(浏览器打开,推荐交付)
└── VERSION.txt
不包含:backend/、web-admin/、Dockerfile、.vue / .py 业务源码。
数据库脚本 zkxw.sql 仅为表结构与基线数据,非应用源代码。
Nginx 反代配置已打入 zkxw-web 镜像,无需单独配置。
4. 甲方服务器上线步骤
# 1) 安装 Docker + Compose(若未安装)
docker --version && docker compose version
# 2) 上传并解压交付包
mkdir -p /opt/zkxw && cd /opt/zkxw
tar -xzf zkxw-docker-deploy-*.tar.gz
cd zkxw-docker-deploy-*
# 3) 导入应用镜像(前后端,无源码)
docker load -i images/zkxw-app-images.tar
docker images | grep zkxw-
# 4) 配置并启动
cd deploy/docker
cp .env.example .env
vi .env # 改密码;确认 ZKXW_BACKEND_IMAGE / ZKXW_WEB_IMAGE 与 load 的 tag 一致
# 5) 启动(会拉取 mysql:5.7.36、redis、minio 等基础镜像,无需 --build)
docker compose up -d
# 6) 查看进度(首次 MySQL 导入约 1~3 分钟)
docker compose ps
docker compose logs -f mysql
docker compose logs -f backend
# 7) 验收
curl -s http://127.0.0.1:8112/health
# 浏览器打开 http://<服务器IP>:8112/ 账号 admin / 111111
防火墙 / 安全组放行 TCP 8112。
| 地址 | 说明 |
|---|---|
http://<服务器IP>:8112/ |
Web 管理端 |
http://<服务器IP>:8112/health |
健康检查 |
http://<服务器IP>:8112/docs |
Swagger |
默认账号:admin / 111111(首次登录后请修改)。
默认 COMPOSE_PROFILES=full:自带 MySQL、Redis、MinIO,首次启动自动导入 docs/sql/zkxw.sql。
Mac(M 芯片)本地试跑:mysql:5.7.36 无 arm64 包,compose 已统一 platform: linux/amd64(模拟运行,会慢一些)。不必为 Mac 重新打 zkxw-app-images.tar。
5. 服务架构
浏览器 :8112
└── web(Nginx + 前端静态)
├── /api/* → backend:8111(FastAPI)
└── /minio/zkxw/* → minio:9000(附件,仅容器内网络)
backend → mysql:3306(业务库 zkxw)
→ redis:6379(会话)
→ minio:9000(对象存储)
minio-init(首次/每次 up 时执行一次):自动创建 `MINIO_BUCKET`(默认 zkxw),并设置 **匿名可读(download)**,供 Nginx `/minio/zkxw/` 反代访问附件;上传仍由后端 API 鉴权后写入。
重要:MySQL、Redis、MinIO 不映射宿主机端口,只在 Docker 内部网络通信,不会与甲方已有 3306/6379/9000 服务冲突。对外仅开放 8112。
API 传输:Docker 交付默认关闭前后端 API 加解密(API_ENCRYPT_ENABLED=false / VITE_API_ENCRYPT_ENABLED=false),请求与响应为明文 JSON。若需启用,须同时改 .env 与 web-admin/.env.docker 后重建 backend、web 镜像。
6. 两种部署 Profile
通过 .env 中 COMPOSE_PROFILES 切换。
6.1 full(默认,全栈)
COMPOSE_PROFILES=full
启动:MySQL + Redis + MinIO + 后端 + 前端。
.env 中使用 Docker 服务名:
DATABASE_URL=mysql+pymysql://root:<密码>@mysql:3306/zkxw
REDIS_HOST=redis
MINIO_ENDPOINT=minio:9000
MINIO_BASE_URL=/minio/zkxw
6.2 app(仅应用,连接甲方已有中间件)
甲方已有 MySQL、Redis、MinIO 时使用:
COMPOSE_PROFILES=app
DATABASE_URL=mysql+pymysql://user:pass@10.0.0.10:3306/zkxw
REDIS_HOST=10.0.0.11
REDIS_PORT=6379
MINIO_ENDPOINT=10.0.0.12:9000
MINIO_ACCESS_KEY=...
MINIO_SECRET_KEY=...
MINIO_BUCKET=zkxw
MINIO_BASE_URL=http://10.0.0.12:9000/zkxw
docker compose up -d --build
注意:若 MinIO 不在 Docker 网络内,需同步修改 web-admin/.env.docker 中的 VITE_MINIO_BASE_URL 并重新构建 web 镜像;或保留 MinIO 容器见下节。
6.3 app,storage(外部库 + 自带 MinIO)
已有 MySQL/Redis,但希望 MinIO 仍由本 compose 提供:
COMPOSE_PROFILES=app,storage
.env 中 DATABASE_URL、REDIS_HOST 指向甲方地址;MINIO_ENDPOINT 仍用 minio:9000。
7. 常用运维命令
cd deploy/docker
# 停止
docker compose down
# 重启
docker compose restart
# 仅重建后端
docker compose up -d --build backend
# 仅重建前端
docker compose up -d --build web
# 查看日志
docker compose logs -f backend
docker compose logs -f web
# 进入后端容器
docker compose exec backend bash
8. 数据持久化与备份
Docker 卷(docker volume ls | grep zkxw):
| 卷名 | 内容 |
|---|---|
zkxw_mysql_data |
MySQL 数据 |
zkxw_redis_data |
Redis 持久化 |
zkxw_minio_data |
附件对象 |
zkxw_backend_uploads |
本地存储模式下的上传目录 |
MySQL 备份示例:
docker compose exec mysql mysqldump -uroot -p zkxw > zkxw_backup.sql
警告:docker compose down -v 会删除所有卷,导致数据丢失。
9. 升级发版
cd /opt/zkxw/zkxw-docker-deploy-<新版本>
# 1) 备份数据库与 MinIO 卷
# 2) 导入新应用镜像
docker load -i images/zkxw-app-images.tar
# 3) 更新 deploy/docker/.env 中 ZKXW_BACKEND_IMAGE、ZKXW_WEB_IMAGE
cd deploy/docker
docker compose up -d
# 4) 验证
curl -s http://127.0.0.1:8112/health
若仅有数据库结构变更,由交付方提供增量 SQL,不要删除已有 mysql_data 卷。
10. 环境变量要点
| 变量 | 说明 |
|---|---|
HTTP_PORT |
对外端口,默认 8112 |
MYSQL_ROOT_PASSWORD |
MySQL root 密码(full profile) |
DATABASE_URL |
须与 MySQL 账号密码一致 |
SECRET_KEY |
JWT 密钥,生产必须改为长随机串 |
API_ENCRYPT_ENABLED |
Docker 交付默认 false(前后端 API 不加密) |
MINIO_* |
对象存储;bucket 由 minio-init 自动创建并设为匿名下载(供 /minio/zkxw/ 访问) |
修改 .env 后:
docker compose up -d
docker compose restart backend
修改 web-admin/.env.docker 后须重建 web:
docker compose up -d --build web
11. 常见问题
8112 无法访问
- 检查防火墙 / 安全组是否放行 8112
docker compose ps确认web为 runningdocker compose logs web
/api 返回 502
- 后端未就绪:
docker compose logs backend - MySQL 初始化未完成(首次启动约 1~3 分钟):
docker compose logs mysql
数据库初始化失败需重来
仅首次部署失败且可接受清空数据时:
docker compose down -v
docker compose up -d
附件无法访问
- 确认
STORAGE_TYPE=minio docker compose logs minio-init(应看到 bucket 创建与anonymous set download成功)- 浏览器 Network 中附件 URL 应为
/minio/zkxw/... - 若 bucket 在加入匿名策略前已存在,可手动执行:
docker compose run --rm minio-init或删除minio_data卷后重新up(会清空附件)
拉取镜像慢或失败
见上文 §1.1 Docker 镜像加速,配置 registry-mirrors 后重试 docker compose up -d。
发版方打包时 pip / pnpm 很慢或超时
- 已默认 阿里云 PyPI + npmmirror,并启用 BuildKit 缓存。
- 若前端构建在
corepack prepare pnpm@...报错(请求registry.npmjs.org失败),请更新到含COREPACK_NPM_REGISTRY的 Dockerfile,或手动指定:NPM_REGISTRY=https://registry.npmmirror.com ./scripts/package-docker-deploy.sh v1.0.0 - 在 Mac(M 芯片)上交叉构建
linux/amd64很慢(后端 pip 常见 15~40 分钟),日志会长时间不动,不要误按 Ctrl+C。 - 推荐:把仓库放到 Linux x86 云主机(与甲方同架构),在该机器执行
./scripts/package-docker-deploy.sh,通常 5~15 分钟完成。
默认已使用阿里云 PyPI(mirrors.aliyun.com)。若需改用清华源:
PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \
PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn \
./scripts/package-docker-deploy.sh v1.0.0
12. 与手工部署的关系
本方案与 测试环境部署/README.md 中「Nginx 8112 + 同域 /api 反代」拓扑一致。应用以预构建镜像交付,甲方执行 docker load + docker compose up -d 即可,无需源码与 pnpm/pip 构建环境。