Beaver Habit Tracker v0.10.0 Docker Compose 部署指南
官方镜像 daya0576/beaverhabits:0.10.0 的 Docker Compose 生产部署实战:镜像标签选型、bind mount 持久化、环境变量注入、升级回滚备份与 7 类故障排障,全部命令实测。
Beaver Habit Tracker v0.10.0 Docker Compose 部署指南
目标:使用 Docker Compose 在 Linux 服务器上部署 Beaver Habit Tracker(BeaverHabits)v0.10.0,以官方镜像
daya0576/beaverhabits:0.10.0运行,通过 bind mount 持久化数据目录,并给出升级、回滚、备份与排障的完整运维闭环。全文命令均在 Ubuntu 22.04 + Docker 29.8.0 环境逐条实测通过,示例管理账号admin@example.com/q1w2e3r4。若您希望脱离容器、在裸机上以 systemd 托管运行,请参阅 《Ubuntu 22.04 安装 Beaver Habit Tracker v0.10.0 指南》。
一、环境信息
本文实测环境与软件版本如下(版本查询日期 2026-10-22):
| 项目 | 值 |
|---|---|
| 服务器操作系统 | Ubuntu 22.04(x86_64) |
| Docker Engine | 29.8.0(build 88096ef,实测 docker --version) |
| Docker Compose | v5.5.1(compose 插件,实测 docker compose version) |
| BeaverHabits 版本 | v0.10.0(2026-07-30 发布,官方最新稳定版) |
| 官方镜像 | daya0576/beaverhabits(Docker Hub) |
| 镜像标签 | 0.10.0(摘要 sha256:d39bea489faedfbc55a29bb73bd8bd1845f52e406dd77ba264bd20ba1439e1e8,实测 docker images ID d39bea489fae) |
| 默认端口 | 8080 |
| 数据目录 | /app/.user/(bind mount 至宿主机) |
| 开源许可 | BSD-3-Clause |
部署完成后可通过 /login 页面访问 Web 界面。组件背景、功能特性与同类选型对比见 《Beaver Habit Tracker v0.10.0 介绍与选型指南》。
二、镜像选型说明
BeaverHabits 官方在 Docker Hub 仅维护一个镜像仓库 daya0576/beaverhabits,基于 python:3.14-slim 构建,内置健康检查(python healthcheck.py,30 秒间隔 / 3 秒超时 / 3 次重试),默认以 nobody 用户运行应用进程,入口命令为 sh start.sh prd(即以生产模式启动 gunicorn,单 worker)。镜像内容大小 117MB、磁盘占用 505MB(实测 docker images)。
可用镜像标签如下(Docker Hub 实查,2026-10-22):
| 标签 | 说明 | 推送时间 |
|---|---|---|
0.10.0 | v0.10.0 稳定版,推荐生产使用 | 2026-07-26 |
latest | 最新稳定版(当前与 0.10.0 指向同一镜像) | 2026-07-26 |
nightly | 每夜构建(main 分支最新代码),仅测试用 | 2026-09-17 |
sha-4b3bc6d | 按 git commit 短哈希构建(4b3bc6d 即 v0.10.0) | 2026-07-26 |
⚠️ 标签不带
v前缀:源码仓库的版本 tag 是v0.10.0,但 Docker Hub 镜像标签是0.10.0。docker pull daya0576/beaverhabits:v0.10.0会报manifest unknown(标签不存在),这是官方仓库的命名约定,不是镜像缺失。
对版本敏感的生产环境,建议固定使用 0.10.0 这样的版本标签,而不是 latest——latest 会随上游发版漂移,docker compose pull 后可能直接跨大版本。若要绝对锁定,可在 image: 字段写摘要形式 daya0576/beaverhabits@sha256:d39bea489faedfbc55a29bb73bd8bd1845f52e406dd77ba264bd20ba1439e1e8。
三、前置条件
3.1 Docker 与 Compose 插件
确认服务器已安装 Docker Engine 与 compose 插件(Ubuntu 22.04 可用官方 apt 源安装 docker-ce 与 docker-compose-plugin,过程略):
docker --version
实测回显:
Docker version 29.8.0, build 88096ef
docker compose version
实测回显:
Docker Compose version v5.5.1
要求 Docker Engine 版本不低于 20.10( BeaverHabits 镜像基于 python:3.14-slim 构建,对内核无特殊要求)。
3.2 数据目录与属主
官方 README 明确提示:挂载的数据目录属主必须与容器内运行用户对齐(UID/GID 1000),否则会出现权限错误。本文以 /opt/beaverhabits 为部署根目录:
mkdir -p /opt/beaverhabits && cd /opt/beaverhabits
mkdir -p beaver && chown -R 1000:1000 beaver
执行后确认:
ls -la /opt/beaverhabits
实测回显:
total 16
drwxr-xr-x 3 root root 4096 Oct 22 16:39 .
drwxr-xr-x 1 root root 4096 Oct 22 16:39 ..
drwxr-xr-x 2 1000 1000 4096 Oct 22 16:39 beaver
3.3 端口与防火墙
服务监听 8080 端口。若服务器启用 UFW 防火墙,放行该端口:
ufw allow 8080/tcp
实测回显:
Rule added
Rule added (v6)
四、部署步骤
4.1 编写 docker-compose.yml
在 /opt/beaverhabits/ 下创建 docker-compose.yml:
cat > /opt/beaverhabits/docker-compose.yml <<'EOF'
name: beaver-habit-tracker-0100-stack
services:
beaverhabits:
image: daya0576/beaverhabits:0.10.0
container_name: beaverhabits
user: "1000:1000"
environment:
- HABITS_STORAGE=USER_DISK
- INDEX_HABIT_DATE_COLUMNS=7
- TIME_ZONE=Asia/Shanghai
volumes:
- ./beaver/:/app/.user/
ports:
- "8080:8080"
restart: unless-stopped
EOF
文件内容说明:
name: beaver-habit-tracker-0100-stack:显式声明 Compose 项目名,生成的默认网络与资源均以该名为前缀,避免与其他应用的同名部署目录互相干扰;user: "1000:1000":以 UID/GID 1000 运行,与数据目录属主对齐(见 3.2 节);不指定则镜像默认以nobody运行,写挂载目录时会因属主不符而失败;HABITS_STORAGE=USER_DISK:习惯数据按用户落 JSON 文件(而非 SQLite),便于直接查看与备份,详见第五节;volumes: ./beaver/:/app/.user/:把宿主机beaver/目录挂为容器数据目录,所有持久化数据都落在这里;restart: unless-stopped:进程崩溃或服务器重启后自动拉起(手动docker compose stop的除外)。
4.2 拉取镜像
cd /opt/beaverhabits && docker compose pull
实测回显:
Image daya0576/beaverhabits:0.10.0 Pulling
Image daya0576/beaverhabits:0.10.0 Pulled
4.3 启动服务
docker compose up -d
实测回显:
Network beaver-habit-tracker-0100-stack_default Creating
Network beaver-habit-tracker-0100-stack_default Creating
Network beaver-habit-tracker-0100-stack_default Created
Network beaver-habit-tracker-0100-stack_default Created
Container beaverhabits Creating
Container beaverhabits Created
Container beaverhabits Starting
Container beaverhabits Started
4.4 确认运行状态
启动后立即查看(健康检查间隔 30 秒,刚启动时状态为 health: starting):
docker compose ps
实测回显:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
beaverhabits daya0576/beaverhabits:0.10.0 "sh start.sh prd" beaverhabits 3 seconds ago Up 3 seconds (health: starting) 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
约 30 秒后健康检查通过,再次确认:
docker compose ps
实测回显:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
beaverhabits daya0576/beaverhabits:0.10.0 "sh start.sh prd" beaverhabits 43 seconds ago Up 43 seconds (healthy) 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
查看启动日志确认应用就绪:
docker compose logs beaverhabits | tail -8
实测回显:
beaverhabits | [2026-10-22 17:01:20 +0000] [9] [INFO] Using worker: uvicorn_worker.UvicornWorker
beaverhabits | [2026-10-22 17:01:20 +0000] [10] [INFO] Booting worker with pid: 10
beaverhabits | [2026-10-22 17:01:20 +0000] [9] [ERROR] Control server error: [Errno 13] Permission denied: '/.gunicorn'
beaverhabits | 2026-10-22 17:01:21.546 | INFO | beaverhabits.main:<module>:16 - Starting BeaverHabits...
beaverhabits | [2026-10-22 17:01:21 +0000] [10] [INFO] Started server process [10]
beaverhabits | [2026-10-22 17:01:21 +0000] [10] [INFO] Waiting for application startup.
beaverhabits | [2026-10-22 17:01:21 +0000] [10] [INFO] Application startup complete.
beaverhabits | 2026-10-22 17:01:50.010 | INFO | beaverhabits.main:Digest:75 - DIGEST GET /health 200 2ms
⚠️ 日志中的
Control server error: [Errno 13] Permission denied: '/.gunicorn'是 gunicorn 26 的控制套接字告警:镜像以非 root 用户运行,无法在根目录写/.gunicorn控制文件。该告警不影响服务,应用随后正常完成启动,可忽略(详见 11.1 节)。
4.5 验证 HTTP 服务
在服务器本机验证登录页:
curl -s -D - -o /dev/null http://127.0.0.1:8080/login
实测回显:
HTTP/1.1 200 OK
date: Thu, 22 Oct 2026 17:00:33 GMT
server: uvicorn
cache-control: no-store
x-nicegui-content: page
content-length: 12481
content-type: text/html; charset=utf-8
vary: Cookie, Accept-Encoding
set-cookie: session=eyJpZCI6ICJlMzZmMTBhMC03YjQxLTRhZGUtODQ3Zi01OWQ4YThhYTdkYTAifQ==.atpBMg.B6PdFZsw2M5gVT_nXhRNiOnECdc; path=/; Max-Age=1209600; httponly; samesite=lax
x-process-time: 1.7639209982007742
返回 HTTP/1.1 200 OK 且 server: uvicorn 即部署成功。此时可从浏览器访问 http://<服务器IP>:8080,会自动跳转到登录页。
4.6 创建管理账号
首次使用需要注册账号。浏览器访问 http://<服务器IP>:8080/register,或直接调用注册接口(本文以示例管理账号 admin@example.com / q1w2e3r4 演示):
curl -s -X POST http://127.0.0.1:8080/auth/register \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.com","password":"q1w2e3r4"}'
实测回显:
{"id":"66d57e38-2585-4dd6-a9a3-f222d5d5a1a5","email":"admin@example.com","is_active":true,"is_superuser":false,"is_verified":false}
注册成功后用该账号登录 http://<服务器IP>:8080/login 即可开始使用。
五、数据持久化说明
5.1 数据落盘位置
/app/.user/ 是 BeaverHabits 唯一的持久化目录,经 bind mount 映射到宿主机 ./beaver/。其中:
| 文件 | 作用 | 何时生成 |
|---|---|---|
habits.db | 账号库(用户、凭证、API Token),始终为 SQLite | 首次启动,实测 94208 字节 |
<邮箱>.json(如 admin@example.com.json) | 习惯数据(当 HABITS_STORAGE=USER_DISK) | 首次创建习惯后 |
注意:账号与习惯数据是两套独立存储。账号永远存在 habits.db;习惯数据的落盘方式由 HABITS_STORAGE 决定——本文选用 USER_DISK(每用户一个 JSON 文件),默认值为 USER_DATABASE(习惯也存进 habits.db)。两种存储互不相通,切换后旧习惯不会自动迁移,需先在旧存储下通过 GET /api/v1/habits/export 导出、再在新存储下导入。
查看宿主机数据目录(注册账号并创建习惯后):
ls -la /opt/beaverhabits/beaver/
实测回显:
total 108
drwxr-xr-x 2 1000 1000 4096 Oct 22 17:05 .
drwxr-xr-x 3 root root 4096 Oct 22 17:05 ..
-rw-r--r-- 1 1000 1000 98 Oct 22 17:05 admin@example.com.json
-rw-r--r-- 1 1000 1000 94208 Oct 22 17:05 habits.db
所有文件属主为 1000:1000(容器内运行用户),与 3.2 节的属主设置一致。admin@example.com.json 即 USER_DISK 存储下该用户全部习惯数据,内容为一条 "Drink Water" 习惯(98 字节)。
5.2 备份与恢复
数据都在 beaver/ 一个目录里,直接打包即可(先停写更稳妥,也可以不停服直接拷):
cd /opt/beaverhabits
tar czf beaver-backup-$(date +%F).tar.gz beaver/
恢复时停止服务、解包覆盖、属主复位后启动:
cd /opt/beaverhabits
docker compose down
tar xzf beaver-backup-2026-10-22.tar.gz
chown -R 1000:1000 beaver/
docker compose up -d
六、环境变量表
BeaverHabits 遵循十二要素应用(Twelve-Factor)风格,所有配置都通过环境变量注入,镜像内没有配置文件。Compose 部署最常用的环境变量如下(均为 configs.py 定义项,实测验证有效):
| 环境变量 | 默认值 | 说明 | 本文取值 |
|---|---|---|---|
HABITS_STORAGE | USER_DATABASE | 习惯存储方式:USER_DATABASE(SQLite)/ USER_DISK(按邮箱 JSON 文件)/ SESSION(仅内存,重启即失) | USER_DISK |
TIME_ZONE | 空(跟随浏览器时区) | 全局时区,IANA 名称(如 Asia/Shanghai);无效值会导致启动失败 | Asia/Shanghai |
INDEX_HABIT_DATE_COLUMNS | 5 | 首页习惯网格的日期列数 | 7 |
MAX_USER_COUNT | -1(不限制) | 最大用户数;达到上限后注册页不可用(仅作用于 Web 界面) | 默认 |
JWT_SECRET | SECRET | 登录令牌签名密钥,生产环境必须修改 | 建议修改 |
NICEGUI_STORAGE_SECRET | dev | Web 框架浏览器存储加密密钥,生产环境建议修改 | 建议修改 |
TRUSTED_LOCAL_EMAIL | 空 | 配置后该邮箱免登录直达(适合内网单用户) | 默认 |
ENV | dev | 运行模式;镜像入口 start.sh prd 已设为 production,无需覆盖 | 由镜像设置 |
其余参数(界面定制、备份、注册管控等)与取值细节详见 《Beaver Habit Tracker v0.10.0 配置参数详解》。
七、配置参数说明
Compose 部署下修改配置的方式就是修改 docker-compose.yml 的 environment: 段,然后重建容器使其生效:
cd /opt/beaverhabits
docker compose up -d
若配置文件已变更,up -d 会检测到差异并自动重建该服务(数据在挂载目录中不受影响)。实测回显:
Container beaverhabits Recreate
Container beaverhabits Recreated
Container beaverhabits Starting
Container beaverhabits Started
两点注意:
- 配置不落盘:环境变量只存在于容器定义中,修改时直接编辑
docker-compose.yml并纳入版本管理(或自行备份该文件),不要依赖容器内的临时改动; - 无效配置会阻断启动:例如
TIME_ZONE=Bad/Zone会在启动时抛出校验错误、worker 退出,docker compose ps会反复重启,改回合法值后docker compose up -d即可恢复。
八、配置文件挂载
- 唯一需要挂载的是数据目录
./beaver/:/app/.user/。BeaverHabits 没有服务端配置文件,配置全部走环境变量(见第六节),因此不存在「挂载配置文件」这一步; - 不要把宿主机目录挂到
/app:/app是程序与依赖所在(源码、Python 虚拟环境、启动脚本),覆盖挂载会直接破坏镜像内程序; - 日志输出到标准输出/标准错误,由 Docker 统一收集(
docker compose logs查看),无需挂载日志目录; - 如需 HTTPS 或域名访问,建议在 Compose 之外加一层反向代理(如 Nginx/Caddy)转发到
127.0.0.1:8080,此时 compose 的ports:可改为"127.0.0.1:8080:8080"只监听本机回环。
九、等价 docker run 命令
与第四节 compose 等价的 docker run 命令如下(参数逐一对应):
docker run -d \
--name beaverhabits \
-p 8080:8080 \
-u 1000:1000 \
-e HABITS_STORAGE=USER_DISK \
-e TIME_ZONE=Asia/Shanghai \
-e INDEX_HABIT_DATE_COLUMNS=7 \
-v /opt/beaverhabits/beaver/:/app/.user/ \
--restart unless-stopped \
daya0576/beaverhabits:0.10.0
官方 README 给出的快速启动命令(更简形式,数据目录属主用当前用户 UID):
docker run -d --name beaverhabits \
-u $(id -u):$(id -g) \
-e HABITS_STORAGE=USER_DISK \
-v ./beaver/:/app/.user/ \
-p 8080:8080 \
daya0576/beaverhabits:latest
两种方式二选一即可,不要同时运行(8080 端口与数据目录都会冲突)。生产建议用 compose:配置显式成文、项目名隔离、升级回滚操作可审计。
十、常用运维命令
以下命令均在 /opt/beaverhabits(compose 文件所在目录)下执行。
10.1 状态与日志
docker compose ps # 运行状态与健康检查结果
docker compose logs -f # 实时跟踪日志(Ctrl+C 退出)
docker compose logs --tail 50 # 最近 50 行
docker stats beaverhabits # 资源占用
实测 docker stats --no-stream(空闲时):
NAME CPU % MEM USAGE / LIMIT
beaverhabits 0.10% 156.8MiB / 31.3GiB
10.2 启停与重启
docker compose stop # 停止(保留容器)
docker compose start # 再次启动
docker compose restart # 重启
docker compose down # 停止并删除容器与网络(数据目录不受影响)
down 实测回显:
Container beaverhabits Stopping
Container beaverhabits Stopped
Container beaverhabits Removing
Container beaverhabits Removed
Network beaver-habit-tracker-0100-stack_default Removing
Network beaver-habit-tracker-0100-stack_default Removed
10.3 升级版本
升级到新版本只需两步:改 docker-compose.yml 中的 image: 标签,然后拉取并重建:
# 例:升级到未来发布的 0.11.0(发布后以 Docker Hub 实际标签为准)
sed -i 's|daya0576/beaverhabits:0.10.0|daya0576/beaverhabits:0.11.0|' docker-compose.yml
docker compose pull
docker compose up -d
数据目录不随容器销毁,升级后账号与习惯数据自动保留(同一存储方式的前提下)。
10.4 回滚版本
把 image: 标签改回旧版本号,重复 docker compose pull && docker compose up -d 即可。若新旧版本存储结构有差异,回滚前先用 5.2 节的方法备份 beaver/ 目录。
10.5 完全卸载
cd /opt/beaverhabits
docker compose down # 停止并删除容器、网络
docker rmi daya0576/beaverhabits:0.10.0 # 删除镜像
rm -rf /opt/beaverhabits # 删除部署目录(含全部数据,确认无需保留后再执行)
十一、常见问题
11.1 日志出现 Control server error: [Errno 13] Permission denied: '/.gunicorn'
现象:启动日志中夹着一条 [ERROR] Control server error: [Errno 13] Permission denied: '/.gunicorn'。
原因与处理:gunicorn 26 默认会尝试创建控制套接字文件 /.gunicorn,而官方镜像以非特权用户运行,无法在根目录写入。这是良性告警,控制套接字缺失只影响运行中动态调参能力,不影响 Web 服务,日志随后会打出 Application startup complete.。实测服务健康检查正常(healthy)、页面 200。可安全忽略,无需处理。
11.2 启动后页面 500,或日志报数据目录权限错误
现象:docker compose ps 显示 Up 但访问报错,日志出现打开 habits.db 或写入文件的 Permission denied。
原因:宿主机数据目录属主与容器运行用户(UID/GID 1000)不一致。
处理:复位属主并重启:
cd /opt/beaverhabits
chown -R 1000:1000 beaver/
docker compose restart
官方 README 对此有明确提示(P.S.:需保证挂载目录可被 UID 1000 写入)。
11.3 docker pull 报标签不存在
现象:docker pull daya0576/beaverhabits:v0.10.0 报 manifest for daya0576/beaverhabits:v0.10.0 not found。
原因:镜像标签不带 v 前缀(见第二节)。
处理:改用 docker pull daya0576/beaverhabits:0.10.0。
11.4 docker compose ps 一直是 (health: starting)
原因:镜像内置健康检查间隔 30 秒、超时 3 秒、重试 3 次,从启动到首次判定 healthy 最长约 30-40 秒,属正常现象。
处理:稍等后重新执行 docker compose ps。若超过 2 分钟仍为 starting 或转为 unhealthy,查看 docker compose logs beaverhabits 定位启动失败原因(常见为第六节所述的无效环境变量,或 11.2 的权限问题)。
11.5 端口 8080 被占用
现象:docker compose up -d 报 Bind for 0.0.0.0:8080 failed: port is already allocated。
处理:改宿主机映射端口,例如换成 18080:
ports:
- "18080:8080"
再执行 docker compose up -d。容器内始终监听 8080,宿主机端口可任选。
11.6 重建/升级后数据还在吗
只要 volumes: 挂载的 beaver/ 目录未被删除,docker compose down、up -d、版本升级都不会丢数据——容器是临时的,数据目录是持久的。数据会丢的唯一情形是删除了宿主机的 beaver/ 目录本身,因此备份策略应围绕该目录建立(见 5.2 节)。
11.7 配置了 TIME_ZONE 后服务反复重启
现象:日志出现 Value error, Invalid TIME_ZONE 'Bad/Zone'. Must be a valid IANA timezone name (e.g. 'America/New_York', 'Europe/London', 'Asia/Tokyo'). 与 Worker ... exited with code 3,docker compose ps 显示不断重启。
原因:TIME_ZONE 值必须是合法 IANA 时区名(如 Asia/Shanghai、America/New_York),任意非法值都会在校验阶段阻断启动。
处理:改回合法时区名后执行 docker compose up -d。
十二、参考链接
- GitHub 仓库:https://github.com/daya0576/beaverhabits
- 官方部署说明(README Deploy 章节):https://github.com/daya0576/beaverhabits#deploy
- Docker Hub 镜像页:https://hub.docker.com/r/daya0576/beaverhabits
- 环境变量 Wiki:https://github.com/daya0576/beaverhabits/wiki/Env
- 组件介绍与同类选型对比:《Beaver Habit Tracker v0.10.0 介绍与选型指南》
- 裸机安装(systemd 托管):《Ubuntu 22.04 安装 Beaver Habit Tracker v0.10.0 指南》
- 全部配置参数释义:《Beaver Habit Tracker v0.10.0 配置参数详解》
- REST API 与自动化集成:《Beaver Habit Tracker v0.10.0 API 使用详解》