You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.6 KiB
6.6 KiB
HappyWedding 生产部署说明(Linux + Docker 容器)
本文档说明如何在 Linux 单机上以 Python 3.13 容器 + Gunicorn 的方式部署 HappyWedding(hw)。
1. 部署拓扑
部署拓扑固定为:
Internet / 内网入口
-> 宿主机端口(默认 8000,可自行前置 nginx / Caddy / LB)
-> Docker container
-> Gunicorn (0.0.0.0:8000)
-> Flask app (run:app)
约定:
- 不再使用 systemd 托管应用进程
- 应用通过 Docker 容器运行,使用 Docker 的
--restart unless-stopped负责常驻 - Flask 通过环境变量进入
production配置 - 容器启动时会自动执行数据库迁移
- 容器镜像内已包含 Python 运行时依赖与编译后的 CSS 产物
2. 目录约定
本方案统一使用以下目录:
- 应用目录:
/opt/hw - 配置目录:
/opt/hw.conf.d - 环境文件:
/opt/hw.conf.d/hw.env - 可写实例目录:
/opt/hw/instance - CSV 预览目录:
/opt/hw/instance/csv_previews
说明:
/opt/hw同时作为宿主机部署目录和容器内工作目录/opt/hw.conf.d同时作为宿主机配置目录和容器内只读挂载目录/opt/hw/instance会挂载进容器,保留 SQLite、CSV 预览等运行时数据
3. 服务器前置要求
请先在目标主机上准备:
- Linux 主机
- Docker Engine
- 若主机是 Debian / Ubuntu,可使用
scripts/install-linux-container.sh自动安装 - 正式部署前请确认 Docker daemon 已启动
- 若主机是 Debian / Ubuntu,可使用
- 数据库(推荐 MySQL)
- 可访问仓库代码的方式(git clone / rsync / scp 等)
当前脚本不负责安装 MySQL。本方案默认应用运行时只依赖 Docker,不再依赖宿主机 Python / Node 运行环境。
4. 生产配置项
HappyWedding 当前依赖以下关键环境变量:
HW_CONFIG=productionHW_SECRET_KEYDATABASE_URL
推荐从模板开始:
deploy/env/hw.env.example
示例:
HW_CONFIG=production
HW_SECRET_KEY=replace-with-a-long-random-secret
DATABASE_URL=mysql+pymysql://hw_user:replace-password@127.0.0.1:3306/hw
# 可选:Gunicorn worker 数量
# HW_GUNICORN_WORKERS=2
# HW_GUNICORN_PORT=8000
4.1 生成随机密钥
可以直接使用仓库脚本:
bash scripts/generate-secrets.sh
把输出内容填入 /opt/hw.conf.d/hw.env 的 HW_SECRET_KEY=。
4.2 数据库说明
- 正式生产建议使用 MySQL
- SQLite 仅适合轻量或临时环境
- 容器启动时会自动执行:
flask db upgrade
- 是否执行
flask seed-all取决于你是否在首次部署时显式开启RUN_SEED_ALL=1
5. 首次部署步骤
5.1 准备应用代码
将仓库代码放到目标主机,例如:
sudo mkdir -p /opt/hw
sudo rsync -a ./ /opt/hw/
或通过 git:
sudo git clone <your-repo-url> /opt/hw
5.2 执行安装脚本
在仓库根目录执行:
sudo bash scripts/install-linux-container.sh
该脚本会:
- 检查 Docker 是否可用
- 若主机为 apt 系发行版且未安装 Docker,则自动安装 Docker
- 创建
/opt/hw - 创建
/opt/hw.conf.d - 创建
/opt/hw/instance - 创建
/opt/hw/instance/csv_previews - 若
/opt/hw.conf.d/hw.env不存在,则从模板初始化一份
5.3 编辑环境变量文件
打开并修改:
sudo vi /opt/hw.conf.d/hw.env
至少填好:
HW_CONFIG=productionHW_SECRET_KEY=<真实随机密钥>DATABASE_URL=<真实数据库连接串>
5.4 部署应用并执行迁移
执行:
sudo bash scripts/deploy-container.sh
该脚本会:
- 读取
/opt/hw.conf.d/hw.env - 在
/opt/hw下构建 Python 3.13 容器镜像 - 停止并删除旧容器(如存在)
- 挂载:
/opt/hw/instance -> /opt/hw/instance/opt/hw.conf.d -> /opt/hw.conf.d:ro
- 启动容器,并使用
--restart unless-stopped - 容器启动时自动执行
flask db upgrade - 启动 Gunicorn 对外监听
0.0.0.0:8000
如果你确认这是一个全新空库,需要同时初始化基础数据:
sudo RUN_SEED_ALL=1 bash scripts/deploy-container.sh
seed-all会在首次成功执行后写入/opt/hw/instance/.seed-all-complete标记,避免每次重启容器都重复灌种子数据。
6. 镜像与运行时行为
当前镜像交付包含:
- Python 3.13 运行时
requirements.txt的 Python 依赖- Node 构建阶段生成的
app/static/css/main.css - 入口脚本
docker/entrypoint.sh
入口脚本行为:
- 加载
/opt/hw.conf.d/hw.env(若存在) - 设置:
FLASK_APP=run.pyHW_CONFIG=production
- 确保
/opt/hw/instance/csv_previews存在 - 执行
python -m flask db upgrade - 如
RUN_SEED_ALL=1且尚未打过标记,则执行python -m flask seed-all - 启动:
gunicorn --workers ${HW_GUNICORN_WORKERS:-2} --bind 0.0.0.0:${HW_GUNICORN_PORT:-8000} run:app
7. 部署后校验
仓库提供脚本:
scripts/verify-container-deployment.sh
默认检查:
- Docker 容器
hw是否运行中 - Docker health 状态是否 healthy(如镜像含 healthcheck)
- 宿主机
8000端口是否有监听 http://127.0.0.1:8000/health是否返回status=ok
执行:
sudo bash scripts/verify-container-deployment.sh
如需覆盖端口或健康检查地址:
sudo HOST_PORT=18000 HEALTHCHECK_URL="http://127.0.0.1:18000/health" bash scripts/verify-container-deployment.sh
8. 常用管理命令
查看容器状态:
docker ps --filter name=hw
查看容器日志:
docker logs -f hw
重启应用:
docker restart hw
停止应用:
docker stop hw
重新部署最新代码:
cd /opt/hw
sudo bash scripts/deploy-container.sh
sudo bash scripts/verify-container-deployment.sh
9. 已知限制与注意事项
- 当前系统正式发布前仍建议补充 CSRF 防护
- 当前前端样式依赖 Tailwind CLI 编译产物,但该产物已在镜像构建阶段自动生成
- 当前生产配置会强制要求设置
HW_SECRET_KEY与DATABASE_URL,未设置时应用会直接启动失败 - 如果使用 SQLite,请确保
/opt/hw/instance可写 - CSV 导入预览依赖
/opt/hw/instance/csv_previews,目录权限必须正常 - 如你需要对外提供 HTTPS,可自行在容器前增加 nginx / Caddy / LB;当前交付只负责应用容器本身
10. 本轮交付文件索引
Dockerfile.dockerignoredocker/entrypoint.shdeploy/env/hw.env.examplescripts/generate-secrets.shscripts/install-linux-container.shscripts/deploy-container.shscripts/verify-container-deployment.sh