Beaver Habit Tracker v0.10.0 Docker Compose 部署指南

官方镜像 daya0576/beaverhabits:0.10.0 的 Docker Compose 生产部署实战:镜像标签选型、bind mount 持久化、环境变量注入、升级回滚备份与 7 类故障排障,全部命令实测。

Beaver Habit TrackerBeaver Habit Tracker习惯追踪DockerDocker Compose2026/10/23

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 Engine29.8.0(build 88096ef,实测 docker --version)
Docker Composev5.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.0v0.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_STORAGEUSER_DATABASE习惯存储方式:USER_DATABASE(SQLite)/ USER_DISK(按邮箱 JSON 文件)/ SESSION(仅内存,重启即失)USER_DISK
TIME_ZONE空(跟随浏览器时区)全局时区,IANA 名称(如 Asia/Shanghai);无效值会导致启动失败Asia/Shanghai
INDEX_HABIT_DATE_COLUMNS5首页习惯网格的日期列数7
MAX_USER_COUNT-1(不限制)最大用户数;达到上限后注册页不可用(仅作用于 Web 界面)默认
JWT_SECRETSECRET登录令牌签名密钥,生产环境必须修改建议修改
NICEGUI_STORAGE_SECRETdevWeb 框架浏览器存储加密密钥,生产环境建议修改建议修改
TRUSTED_LOCAL_EMAIL空配置后该邮箱免登录直达(适合内网单用户)默认
ENVdev运行模式;镜像入口 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

两点注意:

  1. 配置不落盘:环境变量只存在于容器定义中,修改时直接编辑 docker-compose.yml 并纳入版本管理(或自行备份该文件),不要依赖容器内的临时改动;
  2. 无效配置会阻断启动:例如 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。

十二、参考链接