Skip to content

Docker 部署 ​

镜像策略 ​

触发条件镜像 / 行为用途
main 推送测试 + 推送 …:main / …:main-<sha>稳定主干滚动镜像
dev 推送测试 + 推送 …:dev / …:dev-<sha>开发/预发
Git 标签 v*测试 + 一次推送 …:vX.Y.Z + …:latest正式发版(多架构)
手动 workflow_dispatch按当前分支走对应标签规则应急补镜像

发版流程:merge → main(更新 main / main-<sha>)→ 打 vX.Y.Z 并 push tag(更新 vX.Y.Z / latest)。

Actions 运行记录清理 ​

Docker Image 工作流在每次运行结束时(无论测试/构建成功与否)会清理本工作流的历史记录:

  • 至少保留最近 3 次已完成运行
  • 删除 3 天前的其余已完成运行
  • 无定时任务,仅随本工作流触发

快速部署 ​

docker run ​

bash
docker run -d \
  --name tg-signpulse \
  --restart unless-stopped \
  -p 8080:8080 \
  -v $(pwd)/data:/data \
  -e TZ=Asia/Shanghai \
  -e APP_SECRET_KEY=$(openssl rand -base64 32) \
  -e ADMIN_PASSWORD=your_strong_password \
  ghcr.io/silentely/tg-signpulse:latest

Docker Compose(推荐) ​

yaml
services:
  app:
    image: ghcr.io/silentely/tg-signpulse:latest
    container_name: tg-signpulse
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - ./data:/data
    environment:
      PORT: 8080
      TZ: Asia/Shanghai
      APP_DATA_DIR: /data
      APP_SECRET_KEY: replace-with-a-long-random-string
      ADMIN_PASSWORD: replace-with-a-strong-password
      APP_SCHEDULER_LOCK: "1"
      # APP_DATABASE_URL: postgresql+psycopg2://...
      # APP_MONITOR_SHARD: "0/2"
    mem_limit: 768m
    cpus: 1.0
    init: true
    read_only: true
    tmpfs:
      - /tmp
      - /app/__pycache__
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    stop_grace_period: 30s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

启动:

bash
docker compose up -d

上线后快速自检 ​

bash
curl -sS http://127.0.0.1:8080/readyz
# 期望: {"status":"ready","scheduler_lock_held":true,"legacy_tasks_removed":true,"legacy_tasks_writable":false,...}

curl -sS -H "Authorization: Bearer <token>" http://127.0.0.1:8080/api/ops/runtime-status
# 旧 /api/tasks 已移除;ORM 残留盘点: python tools/check_legacy_tasks.py --json

更多边界说明见 运维手册 - 上线检查清单。

本地源码构建 ​

仓库根目录的 Dockerfile 为多阶段构建(Node 构建前端 → Python 运行时)。需要基于未发布的本地改动构建镜像时:

bash
docker build -t tg-signpulse:local .

docker run -d \
  --name tg-signpulse \
  --restart unless-stopped \
  -p 8080:8080 \
  -v $(pwd)/data:/data \
  -e TZ=Asia/Shanghai \
  tg-signpulse:local

端口与健康检查 ​

端点说明
:8080容器默认监听端口
GET /healthz快速健康检查
GET /readyz服务就绪检查(启动完成后返回 200)

Docker 内置健康检查已配置,间隔 30s,超时 10s。

数据持久化 ​

必须挂载 /data,否则所有数据在容器重建后丢失。

/data 目录包含:

text
/data
├── db.sqlite                    # 主数据库
├── .app_secret_key              # JWT 密钥
├── .admin_bootstrap_password    # 初始密码
├── .global_settings.json        # 全局设置
├── .openai_config.json          # AI 配置
├── .telegram_api.json           # Telegram API 配置
├── logs/                        # 执行日志
├── sessions/                    # Telegram 会话
├── plugins/                     # 自定义 Action 插件
└── .signer/                     # 签到引擎数据

⚠️ 如果 /data 不可写,程序会降级到 /tmp/tg-signpulse(非持久化),仅适合临时测试。

⚠️ 防呆说明(单实例 / 单 Worker 约束): 系统采用本地文件化配置与进程内互斥锁(path_write_lock)。生产部署时请保持单副本(Single Replica)与单 Worker(默认 Uvicorn 启动项)运行:

  1. 切勿在 Kubernetes / 容器编排中使用多副本(replicas > 1)同时挂载同一个 NFS / 共享存储卷,否则多个 API 副本并发修改同一任务配置时会导致跨进程写入覆盖(丢失更新)。
  2. 切勿在容器启动命令中添加 --workers N 启动多个 Worker 进程。 高并发请求依靠 FastAPI / Uvicorn 异步 IO 即可满足;若需多实例容灾或监控分片,请参考 架构设计 - 扩展约束。

权限处理 ​

容器入口脚本会自动:

  1. 检测 /data 挂载目录的属主 UID/GID
  2. 以该 UID/GID 身份运行应用
  3. 修复 /data 下文件的权限(确保可写)

如果不需要自动修复权限:

bash
APP_AUTO_FIX_DATA_PERMS=0

默认容器用户:UID=10001, GID=10001。

反向代理 ​

生产环境若需 TLS 终止、SSE / WebSocket 正确转发,请使用完整样例:

最小 Nginx(仅 HTTP 反代) ​

nginx
server {
    listen 80;
    server_name panel.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Caddy ​

panel.example.com {
    reverse_proxy 127.0.0.1:8080
}

💡 使用反向代理时,建议将容器端口绑定到本地:-p 127.0.0.1:8080:8080
SSE 路径 /api/events/ 必须关闭 proxy_buffering,详见 nginx.md。

CI/CD 缓存 ​

镜像构建建议分层缓存:

  • 前端:先复制 frontend/package*.json 并运行 npm install,再复制源码构建。
  • 后端:优先缓存 Python wheel / pip 下载目录,依赖文件变化时再失效。
  • Docker Buildx:启用 registry cache 或 GitHub Actions cache,减少多平台构建耗时。

预发流程建议:

  1. 每次主分支构建推送 test-<short-sha>。
  2. 预发环境显式部署该 sha 标签并验证。

基于 VitePress 构建 · 默认 SQLite,可选 PostgreSQL