Chhoto URL 7.10.3 Docker Compose 部署指南
Chhoto URL 7.10.3 Docker Compose 部署实测:镜像档位选择、compose.yaml 逐项配置与启动日志解读、healthz 健康检查、建链跳转与 hits 异步落库踩坑、数据持久化与自动备份验证(2026-10-30 实测)。
Chhoto URL 7.10.3 Docker Compose 部署指南
目标:本文是 Chhoto URL 的部署篇,给出 Docker Compose 主形态下从零到可用的完整路径:镜像档位选择、compose.yaml 逐项配置、启动日志逐行解读、健康检查、建链跳转实测、数据持久化与自动备份验证。全部命令与输出基于 v7.10.3 容器实测(2026-10-30,单机 Docker 环境),选型与架构认知见《Chhoto URL 介绍与选型指南》。
一、部署前准备
1.1 环境要求
| 项目 | 要求 | 本篇实测环境 |
|---|---|---|
| 容器运行时 | Docker 24+(官方支持 Docker 与 Podman) | Docker 29.x |
| 编排工具 | Docker Compose v2(docker compose 子命令) | Compose v2 |
| 端口规划 | 宿主任选端口 → 容器固定 4567(应用监听端口硬编码,只能改映射侧) | 8130 → 4567 |
| 数据目录 | 无需预建,使用 named volume 挂载 /data | chhoto-url-7103-stack_data |
| 磁盘占用 | 镜像 alpine 档压缩后 <10 MB,数据库初始约 45 KB | 首启后卷内约 180 KB |
Compose 环境本身尚未就绪的,先参考《Docker Compose 安装与多容器编排》完成安装;CHHOTO_* 环境变量属于进程级配置,与 Docker 守护进程配置(参见《Docker daemon.json 配置参数详解》)互不影响。
1.2 镜像档位选择
Chhoto URL 官方在 Docker Hub 与 GHCR 双渠道发布同一镜像(dev 系仅 GHCR),同一 tag 覆盖 amd64/arm64/armv7/riscv64 四架构。v7.10.3 可用的三个档位:
| 镜像档位 | 基础 | 特点 | 健康检查 |
|---|---|---|---|
sintan1729/chhoto-url:latest(scratch) | 空镜像 | 压缩后 <6 MB,无 shell、无 wget | 不可用官方 wget 探针,需改用 CMD 直连探测或放弃 |
sintan1729/chhoto-url:alpine | alpine | 压缩后 <10 MB,含 wget 等基础工具 | 官方 compose 样例原生支持 |
ghcr.io/sintan1729/chhoto-url:dev | alpine | 开发测试版,官方明确不建议生产 | 同 alpine |
本篇选 alpine 档:官方 compose 样例的 healthcheck 依赖容器内 wget,scratch 档没有。除非对镜像体积有极端要求,alpine 档是兼顾可运维性的默认选择。
二、compose.yaml 编写(主形态)
2.1 实测同款完整配置
name: chhoto-url-7.10.3-stack
services:
chhoto-url:
image: sintan1729/chhoto-url:alpine
container_name: chhoto-url-7.10.3-web
restart: unless-stopped
tty: true
ports:
- "8130:4567"
environment:
- CHHOTO_DB_URL=/data/urls.sqlite
- CHHOTO_SQLITE_USE_WAL_MODE=True
- CHHOTO_PASSWORD=CHANGE_ME_STRONG_PASS # 管理密码,生产必须修改;支持 Argon2 哈希
- CHHOTO_EXIT_ON_NO_AUTH=True # 未配置任何认证时拒绝启动,防裸奔
- CHHOTO_API_KEY=CHANGE_ME_LONG_APIKEY # 程序调用用 API Key,与密码二选一也可
- CHHOTO_REDIRECT_METHOD=TEMPORARY # 307 临时跳转,避免浏览器缓存映射
- CHHOTO_SLUG_STYLE=Pair # 形容词-名词对风格短链
- CHHOTO_SITE_URL=http://192.168.1.200:8130 # 对外访问地址,影响生成短链的前缀
volumes:
- data:/data
healthcheck:
test: wget -qO- http://127.0.0.1:1729/healthz || exit 1
interval: 60s
start_period: 10s
retries: 3
timeout: 10s
volumes:
data:
2.2 逐项说明
| 配置项 | 取值 | 说明 |
|---|---|---|
ports | 8130:4567 | 应用进程固定监听 4567(官方硬编码,容器内无对应环境变量),改宿主侧即可 |
CHHOTO_DB_URL | /data/urls.sqlite | SQLite 数据库文件路径,必须落在卷内才有持久化 |
CHHOTO_SQLITE_USE_WAL_MODE | True | 开启 WAL 日志模式,官方强烈建议;启动日志会打印 Using WAL journaling mode |
CHHOTO_PASSWORD | 明文或 Argon2 哈希 | 管理界面与 API 共用;明文时启动日志出现 WARN,建议预存 Argon2 哈希 |
CHHOTO_EXIT_ON_NO_AUTH | True | 密码与 OIDC 都未配置时进程直接退出(退出码 1),防止无认证暴露公网 |
CHHOTO_API_KEY | 长随机串 | 供 REST API 调用方使用,请求头 X-API-Key,详见本专栏 API 篇 |
CHHOTO_REDIRECT_METHOD | TEMPORARY / PERMANENT | 对应 HTTP 307 / 308,默认 PERMANENT;本篇实测用 TEMPORARY |
CHHOTO_SLUG_STYLE | Pair / UID | Pair 生成「形容词-名词」易读短链;UID 为随机字符串 |
CHHOTO_SITE_URL | 对外可达地址 | 创建短链时返回的 shorturl 前缀取自这里,填错不影响跳转只影响展示 |
restart | unless-stopped | 守护进程重启后自动拉起,手工 stop 则不拉 |
tty: true | — | 保持标准输出可用,便于 docker logs 观察访问日志 |
healthcheck | wget → 127.0.0.1:1729 | 应用在回环地址额外监听 /healthz,返回 healthy/unhealthy,不占用对外端口 |
三、启动与首启验证
3.1 拉起与启动日志
docker compose up -d
docker logs -f chhoto-url-7.10.3-web
v7.10.3 首启日志实测摘录(去掉颜色码,按顺序):
Starting Chhoto URL Server v7.10.3
Allowed protocols: {"ftp", "magnet", "https", "http"}
WARN Using plaintext for password and API key verification. Argon2 is advised.
Configured Site URL: http://192.168.1.200:8130
Using adjective-noun pair slugs.
Capital letters won't be allowed in links.
Using WAL journaling mode for database.
Ensuring ACID compliance, using synchronous pragma: FULL.
Creating an init backup of the database.
Initializing database.
Database initialization was successful.
Server has started listening to 0.0.0.0 on port 4567.
Starting database cleanup service, will run once every hour.
No expired links were found.
逐行解读:允许的长链协议白名单默认 4 种(可追加);密码/API Key 为明文时给出 Argon2 建议(WARN 不阻断);随后依次回显站点地址、短链风格、大小写策略、WAL 与 ACID 级别;每次容器首启都会先做一次数据库初始化备份再建库;过期短链清理服务每小时跑一次。
3.2 健康检查确认
/healthz 只绑定在容器内 127.0.0.1:1729,不通过 4567 对外暴露,属专用存活探针端点:
docker exec chhoto-url-7.10.3-web wget -qO- http://127.0.0.1:1729/healthz
# 输出:healthy
docker ps --filter name=chhoto-url --format '{{.Status}}'
# 输出:Up (healthy)
3.3 无认证快速探针
两个只读路由无需任何认证,是部署后确认服务存活最快的探针(官方 docs/CLI.md 口径,实测输出):
curl http://localhost:8130/api/version # → Chhoto URL v7.10.3
curl http://localhost:8130/api/siteurl # → http://192.168.1.200:8130
带认证的 /api/getconfig 能一次性回显生效配置,适合核对环境变量是否按预期加载(输出节选):
{"version":"7.10.3","site_url":"http://192.168.1.200:8130","allow_capital_letters":false,
"public_mode":false,"allowed_protocols":["ftp","magnet","https","http"],
"slug_style":"Pair","slug_length":8,"try_longer_slug":false,"frontend_page_size":10}
四、建链与跳转实测
4.1 创建短链
REST 方式创建(也可在网页管理界面操作,二者等价):
# 自定义短链别名
curl -s -X POST -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"longlink": "https://www.quzuo.net/", "shortlink": "quzuo-home"}' \
http://localhost:8130/api/new
# → {"success":true,"error":false,"shorturl":"http://192.168.1.200:8130/quzuo-home","enabled":true,"expiry_time":0}
# 不传 shortlink,Pair 风格自动生成
curl -s -X POST -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
-d '{"longlink": "https://docs.quzuo.net/guide/intro?tab=advanced&v=2"}' \
http://localhost:8130/api/new
# → {"success":true,...,"shorturl":"http://192.168.1.200:8130/buck-elastic",...}
自动生成的 buck-elastic 正是「形容词-名词」对格式;长链接里的查询串与多参数原样保留。
4.2 跳转语义实测
curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}\n" http://localhost:8130/quzuo-home
# → 307 -> https://www.quzuo.net/
CHHOTO_REDIRECT_METHOD=TEMPORARY 生效为 307 临时跳转,浏览器每次访问都会回源询问,改目标地址后立即生效;若为 PERMANENT 则返回 308,浏览器可能长期缓存旧映射。
4.3 两个实测踩坑
踩坑一:HEAD 请求 404,探针必须用 GET。 用 curl -I(HEAD 方法)访问短链会得到 404 页面,而同一 URL 的 GET 请求正常 307——v7.10.3 的跳转路由只注册了 GET 语义,HEAD 会落入 404 兜底分支,且不产生命中计数。监控脚本、拨测工具若以 HEAD 探活短链会全部误报,务必改用 GET 探测。
踩坑二:hits 计数为异步批量落库,初查为 0 系探针过快。 访问短链后立刻查询 /api/all,hits 仍显示旧值甚至 0:命中计数经内存通道由后台 worker 批量写库(实测约 500 ms~1 s 内可见 +1)。正确姿势是访问后等待 1 秒以上再查,不要把「计数不涨」误判为统计失效。
五、数据持久化与自动备份
5.1 卷内数据结构
named volume 挂载在 /data,实测文件布局:
/data
├── urls.sqlite # 主数据库(WAL 模式下约 45 KB 起)
├── urls.sqlite-wal # WAL 预写日志(运行中 90 KB 上下浮动)
├── urls.sqlite-shm # WAL 共享内存索引
└── backups/
├── urls.sqlite.init.2026-10-30T04-06-34Z # 首启 init 备份
└── urls.sqlite.init.2026-10-30T04-08-33Z # 第二次容器首启又做一次 init 备份
自动备份策略(官方口径):初始化时与每日 3-4 点间各备份一次,保留最近 3 份初始化备份与 7 份每日备份;如需接管备份节奏可用 CHHOTO_DISABLE_BACKUPS 关闭后自建定时任务,SQLite 层面的备份/恢复方法可参考《SQLite 备份与恢复指南》。
5.2 容器重建实测
docker compose down(不带 -v)后重新 up -d,验证数据保留:
重建后: 4 条
docs https://www.quzuo.net hits 4
franklin-stupefied https://example.com hits 0
quzuo-home https://www.quzuo.net/ hits 3
buck-elastic https://docs.quzuo.net/... hits 0
跳转验证: 307 -> https://www.quzuo.net/
短链、命中计数、备注、过期设置全部保留,重建后跳转立即恢复。注意:down -v 会连卷一起删除,等价于清库重来,日常维护只用 down/restart。
六、升级、安全加固与 HTTPS 前置
- 升级:
docker compose pull && docker compose up -d,数据在卷内不动;升级后用/api/version复查版本号。 - 密码加固:日志 WARN 的 Argon2 建议值得落实——把明文密码换为 Argon2 哈希存入
CHHOTO_PASSWORD,即使环境变量泄露也不能直接反推原密码。 - HTTPS:应用本身不做 TLS,管理密码以明文穿过网络,生产必须前置反代。Caddy 方案可参考《Caddy 2.11.7 Docker Compose 部署指南》与《Caddy 2 配置参数详解》,Nginx 方案可参考《Nginx 配置参数详解》;反代只需把
Host头透传到 4567 即可,短链跳转由应用自己完成。 - 端口收敛:若只经反代访问,可把 ports 映射改为
127.0.0.1:8130:4567,避免管理面裸露在内网之外。
七、排错清单
| 现象 | 原因 | 处置 |
|---|---|---|
curl -I 访问短链返回 404 | HEAD 方法不命中跳转路由(v7.10.3 行为) | 改用 curl -s -o /dev/null -w "%{http_code}" 的 GET 探针 |
| 访问后 hits 立即查询为 0 | 命中计数异步批量落库(约 500 ms~1 s) | 等待 1 秒后再查,勿误判统计失效 |
| 容器启动即退出(exit 1) | 未配置任何认证且 CHHOTO_EXIT_ON_NO_AUTH=True | 配置 CHHOTO_PASSWORD 或 OIDC 后重启 |
| 日志 WARN 提示 Argon2 | 密码/API Key 为明文存储 | 换用 Argon2 哈希写入环境变量 |
docker logs 无访问日志 | 未开 tty 或未加 Compress/Logger 中间件对应配置 | compose 加 tty: true 后重建容器 |
| 短链跳转 404 但列表里存在 | 访问的短链名与库里大小写不一致 | allow_capital_letters=false 时别名强制小写,统一用小写访问 |
| 管理界面打不开 | CHHOTO_DISABLE_FRONTEND=True 关闭了前端 | 去掉该变量重建,或纯走 API |
八、本专栏系列导航
- 认知与选型:《Chhoto URL 介绍与选型指南》——架构、特性与同类对比。
- 下一篇:配置参数详解(
CHHOTO_*环境变量全集与生效验证)、REST API 使用详解将陆续发布于本专栏。