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

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. 服务器前置要求

请先在目标主机上准备:

  1. Linux 主机
  2. Docker Engine
    • 若主机是 Debian / Ubuntu,可使用 scripts/install-linux-container.sh 自动安装
    • 正式部署前请确认 Docker daemon 已启动
  3. 数据库(推荐 MySQL)
  4. 可访问仓库代码的方式(git clone / rsync / scp 等)

当前脚本不负责安装 MySQL。本方案默认应用运行时只依赖 Docker,不再依赖宿主机 Python / Node 运行环境。

4. 生产配置项

HappyWedding 当前依赖以下关键环境变量:

  • HW_CONFIG=production
  • HW_SECRET_KEY
  • DATABASE_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.envHW_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

该脚本会:

  1. 检查 Docker 是否可用
  2. 若主机为 apt 系发行版且未安装 Docker,则自动安装 Docker
  3. 创建 /opt/hw
  4. 创建 /opt/hw.conf.d
  5. 创建 /opt/hw/instance
  6. 创建 /opt/hw/instance/csv_previews
  7. /opt/hw.conf.d/hw.env 不存在,则从模板初始化一份

5.3 编辑环境变量文件

打开并修改:

sudo vi /opt/hw.conf.d/hw.env

至少填好:

  • HW_CONFIG=production
  • HW_SECRET_KEY=<真实随机密钥>
  • DATABASE_URL=<真实数据库连接串>

5.4 部署应用并执行迁移

执行:

sudo bash scripts/deploy-container.sh

该脚本会:

  1. 读取 /opt/hw.conf.d/hw.env
  2. /opt/hw 下构建 Python 3.13 容器镜像
  3. 停止并删除旧容器(如存在)
  4. 挂载:
    • /opt/hw/instance -> /opt/hw/instance
    • /opt/hw.conf.d -> /opt/hw.conf.d:ro
  5. 启动容器,并使用 --restart unless-stopped
  6. 容器启动时自动执行 flask db upgrade
  7. 启动 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

入口脚本行为:

  1. 加载 /opt/hw.conf.d/hw.env(若存在)
  2. 设置:
    • FLASK_APP=run.py
    • HW_CONFIG=production
  3. 确保 /opt/hw/instance/csv_previews 存在
  4. 执行 python -m flask db upgrade
  5. RUN_SEED_ALL=1 且尚未打过标记,则执行 python -m flask seed-all
  6. 启动:
gunicorn --workers ${HW_GUNICORN_WORKERS:-2} --bind 0.0.0.0:${HW_GUNICORN_PORT:-8000} run:app

7. 部署后校验

仓库提供脚本:

  • scripts/verify-container-deployment.sh

默认检查:

  1. Docker 容器 hw 是否运行中
  2. Docker health 状态是否 healthy(如镜像含 healthcheck)
  3. 宿主机 8000 端口是否有监听
  4. 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. 已知限制与注意事项

  1. 当前系统正式发布前仍建议补充 CSRF 防护
  2. 当前前端样式依赖 Tailwind CLI 编译产物,但该产物已在镜像构建阶段自动生成
  3. 当前生产配置会强制要求设置 HW_SECRET_KEYDATABASE_URL,未设置时应用会直接启动失败
  4. 如果使用 SQLite,请确保 /opt/hw/instance 可写
  5. CSV 导入预览依赖 /opt/hw/instance/csv_previews,目录权限必须正常
  6. 如你需要对外提供 HTTPS,可自行在容器前增加 nginx / Caddy / LB;当前交付只负责应用容器本身

10. 本轮交付文件索引

  • Dockerfile
  • .dockerignore
  • docker/entrypoint.sh
  • deploy/env/hw.env.example
  • scripts/generate-secrets.sh
  • scripts/install-linux-container.sh
  • scripts/deploy-container.sh
  • scripts/verify-container-deployment.sh