Ubuntu 22.04 安装 Beaver Habit Tracker v0.10.0 指南
Ubuntu 22.04 源码安装 BeaverHabits v0.10.0 实战:uv 与 pip 双方案 0→1 安装、systemd 托管、配置、升级回滚与 7 类故障排障,全部命令实测。
Ubuntu 22.04 安装 Beaver Habit Tracker v0.10.0 指南
目标:在 Ubuntu 22.04 服务器上从零安装 Beaver Habit Tracker(BeaverHabits)v0.10.0,并以 systemd 托管为常驻生产服务。全文提供两种安装方案:方案 A 使用官方推荐的 uv 工具链(锁版本、可复现),方案 B 使用系统 Python + pip(不引入额外工具链),两种方案均给出完整命令与实测回显。已在 Ubuntu 22.04(x86_64)环境逐条实测通过,安装根目录
/opt/beaverhabits,数据目录/opt/beaverhabits/.user/,服务端口 8080,示例管理账号admin@example.com/q1w2e3r4。
一、环境信息
本文所有命令与回显均在以下环境实测(2026-10-22):
- 操作系统:Ubuntu 22.04 LTS(x86_64,内核 5.15+ 均适用)
- 应用版本:Beaver Habit Tracker v0.10.0(源码标签 v0.10.0,对应提交 4b3bc6d)
- Python:3.12.15(deadsnakes PPA 安装,系统级
/usr/bin/python3.12) - 包管理工具:uv 0.13.5(方案 A)/ pip 25.0.1(方案 B)
- 应用服务器:gunicorn 26.x + uvicorn-worker(单 worker,监听 0.0.0.0:8080)
- 安装目录:
/opt/beaverhabits;数据目录:/opt/beaverhabits/.user/ - 运行账号:系统服务账号
beaver(无登录 shell) - 服务管理:systemd(单元文件
/etc/systemd/system/beaverhabits.service)
二、前置条件
开始安装前,请确认以下条件已满足。每条都给出检查命令与期望结果,避免装到一半才发现环境缺项。
- 一台 Ubuntu 22.04 服务器,拥有 root 权限(本文命令均以 root 执行;如用普通用户,请在每条命令前加
sudo); - 服务器可访问外网(需访问 GitHub 拉取源码、PyPI 下载依赖包、launchpad.net 添加 PPA);内网隔离环境请直接采用方案 B 的离线思路(见 5.1 方案说明);
- 端口 8080 未被占用(或你计划使用的其他端口),检查命令:
ss -ltn | grep 8080 || echo "8080 端口空闲"
实测回显(空闲时):
8080 端口空闲
若回显为空但 echo 也未输出,说明命令拼写有误;若 grep 命中了监听行(如 LISTEN 0 511 *:8080),说明端口已被占用,需先释放或在后续配置中改用其他端口。
- 基础工具 git 与 curl(步骤 4.2 一并安装);
- 磁盘空间不少于 1GB(源码约 10MB,依赖虚拟环境约 300-400MB,SQLite 数据随使用增长)。
三、版本选型说明
BeaverHabits 遵循语义化版本,源码标签带 v 前缀(如 v0.10.0),而 Docker Hub 镜像标签不带 v(如 0.10.0)——这是同一版本的两种命名,源码安装一律使用带 v 的标签。近六个稳定版本如下(GitHub releases 实查,查询日期 2026-10-22):
| 版本 | 发布日期 | 关键变化 |
|---|---|---|
| v0.10.0 | 2026-07-30 | 原生客户端实时同步(WebSocket /api/v1/sync/ws)、无损快照导出、iOS TestFlight |
| v0.9.1 | 2026-05-20 | 完成状态总览页、TIME_ZONE 环境变量、自定义 CSS XSS 修复 |
| v0.9.0 | 2026-02-20 | OpenClaw AI 集成、长期 API Token |
| v0.8.2 | 2026-02-03 | 管理员编程创建用户端点 |
| v0.8.1 | 2026-01-04 | streak 图标自定义、skip/failed 状态、全局视图页 |
| v0.8.0 | 2025-12-02 | 备注标签驱动 streak 定制 |
选型建议:新装一律选最新稳定版 v0.10.0(本文实测版本);已运行的旧版本升级方法见第八章。BeaverHabits 版本迭代以功能增强为主、破坏性变更少,紧跟最新稳定版的风险很低;但升级前仍建议按第九章 FAQ 的方式备份 .user/ 目录。
四、方案 A:uv 工具链源码安装(在线,官方推荐)
4.1 方案说明
BeaverHabits 官方开发与构建均使用 uv 工具链(README 明确写有 "BeaverHabits favors uv as package management tool"),仓库自带 uv.lock 锁定文件。本方案用 uv 按 uv.lock 精确复现官方构建的依赖版本组合,可复现性最好,是与官方 Docker 镜像内部构建完全一致的安装路径。
方案主线:装基础依赖 → 装 uv → 装系统级 Python 3.12 → 拉源码 → uv 依赖安装 → 建运行账号 → systemd 托管 → 验证。
4.2 安装基础依赖
更新软件源索引并安装 git、curl(后续拉源码与下载工具用):
apt-get update
实测回显(输出较长,节选首尾):
Get:1 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
...
Get:18 http://archive.ubuntu.com/ubuntu jammy-backports/main amd64 Packages [82.9 kB]
Fetched 49.0 MB in 14s (3549 kB/s)
Reading package lists...
DEBIAN_FRONTEND=noninteractive apt-get install -y git curl ca-certificates
实测回显(节选尾部):
Setting up git (1:2.34.1-1ubuntu1.15) ...
Processing triggers for man-db (2.10.2-1) ...
Running hooks in /etc/ca-certificates/update.d...
done.
⚠️ 注意:若
apt-get update报Temporary failure resolving类错误,说明服务器无法解析域名,请先修复 DNS(检查/etc/resolv.conf)再继续。
4.3 安装 uv
用官方安装脚本安装 uv(安装到当前用户 ~/.local/bin/,本文将其软链到系统路径便于后续使用):
curl -LsSf https://astral.sh/uv/install.sh | sh
ln -sf /root/.local/bin/uv /usr/local/bin/uv
uv --version
实测回显:
uv 0.13.5 (x86_64-unknown-linux-gnu)
💡 说明:uv 是 Rust 编写的 Python 包与项目管理器,替代 pip/venv/virtualenv 的组合,核心优势是全局缓存与
uv.lock锁定文件的确定性安装。若你所在团队已统一使用 pip 工作流,可跳过本节直接采用第五章方案 B。
4.4 安装系统级 Python 3.12
BeaverHabits v0.10.0 要求 Python >=3.12(pyproject.toml 声明 requires-python = ">=3.12,<4.0"),而 Ubuntu 22.04 自带的是 Python 3.10,需要通过社区维护的 deadsnakes PPA 安装 3.12。这里特意选择系统级安装而非让 uv 自动下载 Python:uv 默认把受管 Python 装到执行账号的家目录(root 时为 /root/.local/share/uv/python/),后续 systemd 以 beaver 账号运行服务时会因无权访问该目录而启动失败(实测排障见 4.9 的 ⚠️ 与第九章 FAQ 2)。
DEBIAN_FRONTEND=noninteractive apt-get install -y software-properties-common
add-apt-repository -y ppa:deadsnakes/ppa
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y python3.12
/usr/bin/python3.12 --version
实测回显(add-apt-repository 节选 + 版本验证):
Adding key to /etc/apt/trusted.gpg.d/deadsnakes-ubuntu-ppa.gpg with fingerprint F23C5A6CF475977595C89F51BA6932366A755776
...
Python 3.12.15
4.5 获取源码
克隆 v0.10.0 标签到 /opt/beaverhabits:
git clone --depth 1 --branch v0.10.0 https://github.com/daya0576/beaverhabits.git /opt/beaverhabits
实测回显(节选尾部;--branch 指向标签时 git 会提示 detached HEAD,属正常现象):
Note: switching to '4b3bc6d64548feb3c0a431d70f307be1117a820c'.
...
Turn off this advice by setting config variable advice.detachedHead to false
确认源码完整:
ls /opt/beaverhabits
实测回显:
beaverhabits docker healthcheck.py openclaw pytest.ini start.sh tests
uv.lock README.md fly.toml LICENSE pyproject.toml statics
⚠️ 注意:
--depth 1浅克隆只取 v0.10.0 一个提交,节省时间与磁盘;若后续需要git pull方式升级(第八章),建议改用完整克隆git clone --branch v0.10.0 https://github.com/daya0576/beaverhabits.git /opt/beaverhabits。
4.6 安装依赖(uv sync)
按 uv.lock 锁定版本安装生产依赖。参数与官方 Dockerfile 构建命令保持一致:--frozen 严格按锁定文件不重新解析、--no-dev 跳过开发依赖、--no-install-project 不把应用本身装成包(应用以源码目录直接运行)、--python 显式指定刚装好的系统级 Python:
cd /opt/beaverhabits
uv sync --frozen --no-dev --no-install-project --python /usr/bin/python3.12
实测回显(输出较长,节选尾部):
+ pydantic-settings==2.14.2
+ pygments==2.20.0
+ pyjwt==2.13.0
+ python-dateutil==2.9.0.post0
+ python-dotenv==1.2.2
+ python-engineio==4.13.3
+ python-multipart==0.0.32
+ python-socketio==5.16.3
+ pytz==2024.2
+ pyyaml==6.0.3
+ redis==8.0.0
+ requests==2.34.2
+ sqlalchemy==2.0.51
+ uvicorn==0.49.0
+ uvicorn-worker==0.4.0
+ uvloop==0.22.1
+ websockets==16.0
+ yarl==1.24.2
验证虚拟环境与应用服务器就位:
ls /opt/beaverhabits/.venv/bin/ | grep -E '^(python|gunicorn|uvicorn)$'
实测回显:
gunicorn
python
python3
python3.12
uvicorn
4.7 创建运行账号
创建无登录 shell 的系统服务账号 beaver,并把安装目录属主交给它(数据目录 .user/ 需要写权限):
useradd -r -s /usr/sbin/nologin beaver
mkdir -p /home/beaver
chown -R beaver:beaver /opt/beaverhabits /home/beaver
id beaver
实测回显:
uid=999(beaver) gid=999(beaver) groups=999(beaver)
⚠️ 注意:
/home/beaver目录必须有且属主为beaver——gunicorn 运行时会在用户家目录下创建控制套接字目录.gunicorn/,家目录缺失或不属主时日志会出现Control server error: [Errno 13] Permission denied告警(不影响服务,但建议消除,见第九章 FAQ 3)。
4.8 配置生产启动
BeaverHabits 的生产入口是仓库自带的 start.sh prd,其实际执行的核心命令为(start.sh 实查):
gunicorn beaverhabits.main:app --bind 0.0.0.0:8080 -w 1 -k uvicorn_worker.UvicornWorker --max-requests 10000 --log-level info
三个关键点(配置解读):
-w 1:固定单 worker。BeaverHabits 的 Web 交互基于 socket.io 长连接,多 worker 会导致连接漂移到不同进程而出错,不要改大;-k uvicorn_worker.UvicornWorker:让 gunicorn 承载 uvicorn 的 ASGI 异步运行时;--max-requests 10000:每个 worker 处理 1 万请求后自动重启进程,规避潜在内存缓涨。
环境变量 ENV=production 会启用生产模式(同时默认把 NiceGUI 的浏览器端存储路径设为 .user/.nicegui)。这些将在 systemd 单元中显式声明。
4.9 systemd 托管
创建单元文件 /etc/systemd/system/beaverhabits.service:
cat > /etc/systemd/system/beaverhabits.service <<'EOF'
[Unit]
Description=Beaver Habit Tracker (BeaverHabits)
After=network.target
[Service]
Type=simple
User=beaver
Group=beaver
WorkingDirectory=/opt/beaverhabits
Environment=ENV=production
Environment=NICEGUI_STORAGE_PATH=/opt/beaverhabits/.user/.nicegui
ExecStart=/opt/beaverhabits/.venv/bin/gunicorn beaverhabits.main:app --bind 0.0.0.0:8080 -w 1 -k uvicorn_worker.UvicornWorker --max-requests 10000 --log-level info
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
配置逐项说明:
User/Group=beaver:以低权限服务账号运行,不使用 root;WorkingDirectory=/opt/beaverhabits:应用要求在该目录下启动,beaverhabits包与.user/数据目录都按相对路径解析;Environment=ENV=production:生产模式开关(对应configs.py的ENV字段);Environment=NICEGUI_STORAGE_PATH=...:显式指定 NiceGUI 浏览器端存储目录,避免权限歧义;ExecStart:直接指向虚拟环境内的 gunicorn 绝对路径(等价于start.sh prd,但 systemd 下无需再套一层 shell);Restart=on-failure+RestartSec=5:异常退出 5 秒后自动拉起。
⚠️ 注意(实测排障沉淀):如果 4.4 步没有安装系统级 Python 3.12,而是让 uv 自动下载了受管 Python,本步启动会失败——systemd 日志报
Failed to execute /opt/beaverhabits/.venv/bin/gunicorn: Permission denied、状态码203/EXEC。根因是 uv 把 Python 解释器装在/root/.local/share/uv/python/下,beaver账号无法访问 venv 中指向该路径的python。解决办法就是按 4.4 用系统级 Python 重建虚拟环境(rm -rf .venv后重跑uv sync ... --python /usr/bin/python3.12),详见第九章 FAQ 2。
加载并启用服务(每条命令仅针对一个单元):
systemctl daemon-reload
systemctl enable beaverhabits
实测回显:
Created symlink /etc/systemd/system/multi-user.target.wants/beaverhabits.service → /etc/systemd/system/beaverhabits.service.
systemctl start beaverhabits
4.10 验证
依次确认服务状态、HTTP 服务与监听端口:
systemctl is-enabled beaverhabits
实测回显:
enabled
systemctl is-active beaverhabits
实测回显:
active
systemctl status beaverhabits --no-pager | head -12
实测回显:
● beaverhabits.service - Beaver Habit Tracker (BeaverHabits)
Loaded: loaded (/etc/systemd/system/beaverhabits.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2026-10-22 16:36:39 UTC; 14s ago
Main PID: 2236 (gunicorn)
Tasks: 4 (limit: 94371)
Memory: 145.0M
CPU: 2.133s
CGroup: /system.slice/beaverhabits.service
├─2236 /opt/beaverhabits/.venv/bin/python /opt/beaverhabits/.venv/bin/gunicorn beaverhabits.main:app --bind 0.0.0.0:8080 -w 1 -k uvicorn_worker.UvicornWorker --max-requests 10000 --log-level info
└─2238 /opt/beaverhabits/.venv/bin/python /opt/beaverhabits/.venv/bin/gunicorn beaverhabits.main:app --bind 0.0.0.0:8080 -w 1 -k uvicorn_worker.UvicornWorker --max-requests 10000 --log-level info
应用启动日志(journalctl 节选):
journalctl -u beaverhabits --no-pager -n 5
实测回显:
Oct 22 16:37:06 beaver-server gunicorn[2268]: 2026-10-22 16:37:06.506 | INFO | beaverhabits.main:<module>:16 - Starting BeaverHabits...
Oct 22 16:37:06 beaver-server gunicorn[2268]: [2026-10-22 16:37:06 +0000] [2268] [INFO] Started server process [2268]
Oct 22 16:37:06 beaver-server gunicorn[2268]: [2026-10-22 16:37:06 +0000] [2268] [INFO] Waiting for application startup.
Oct 22 16:37:06 beaver-server gunicorn[2268]: [2026-10-22 16:37:06 +0000] [2268] [INFO] Application startup complete.
HTTP 验证(登录页应返回 200;根路径 / 会 307 跳转到 /login,同样正常):
curl -si --max-time 10 http://127.0.0.1:8080/login | head -3
实测回显:
HTTP/1.1 200 OK
date: Thu, 22 Oct 2026 16:36:53 GMT
server: uvicorn
curl -si --max-time 10 http://127.0.0.1:8080/ | head -4
实测回显:
HTTP/1.1 307 Temporary Redirect
date: Thu, 22 Oct 2026 16:28:56 GMT
server: uvicorn
location: /login
vary: Cookie
最后确认数据文件已自动创建(首次启动即初始化 SQLite 库):
ls -la /opt/beaverhabits/.user/
实测回显:
total 104
drwxr-xr-x 2 beaver beaver 4096 Oct 22 16:36 .
drwxr-xr-x 13 beaver beaver 4096 Oct 22 16:36 ..
-rw-r--r-- 1 beaver beaver 94208 Oct 22 16:36 habits.db
浏览器访问 http://<服务器IP>:8080,看到登录/注册页即安装成功。首次使用先注册账号(示例:admin@example.com / q1w2e3r4,仅本文演示用,生产请更换强口令),再登录创建习惯开始打卡。API 调用与更多验证手段见本专栏《Beaver Habit Tracker v0.10.0 API 使用详解》。
五、方案 B:pip + venv 安装(备用)
5.1 方案说明
不引入 uv 工具链,直接用 Ubuntu 系统级 Python 3.12 创建 venv 并以 pip 安装依赖。适用场景:受管控的服务器不允许安装额外二进制工具、或团队标准就是 pip 工作流。与方案 A 的差异在于依赖解析:方案 A 按 uv.lock 锁定精确版本(如 nicegui==3.13.0),方案 B 按 pyproject.toml 的版本范围解析,实际会装到更新的兼容版本(实测 nicegui==3.18.0、gunicorn==26.2.0),启动与功能验证一致。
方案主线:装 Python 3.12 与 venv 支持 → 拉源码 → 建 venv → pip 装依赖 → 启动验证 → systemd 托管。本方案在 4.4 已装 deadsnakes Python 的基础上只需补装 python3.12-venv;如果服务器还没装 Python 3.12,先按 4.2/4.4 完成基础依赖与 deadsnakes 步骤。
5.2 获取源码与创建虚拟环境
apt-get install -y python3.12-venv
git clone --depth 1 --branch v0.10.0 https://github.com/daya0576/beaverhabits.git /opt/beaverhabits
python3.12 -m venv /opt/beaverhabits/.venv
实测回显(无输出的命令静默成功,验证 venv 就位):
/opt/beaverhabits/.venv/bin/python --version
实测回显:
Python 3.12.15
5.3 安装依赖
按 pyproject.toml 声明的依赖范围用 pip 安装(与 v0.10.0 的 pyproject.toml dependencies 列表一致):
/opt/beaverhabits/.venv/bin/pip install \
'nicegui[redis]>=3.13.0' \
'pydantic-settings<3.0.0,>=2.2.1' \
'fastapi-users[sqlalchemy]>=15.0.0,<16.0.0' \
'uvicorn[standard]>=0.28.0,<1.0.0' \
'sqlalchemy[asyncio]<3.0.0,>=2.0.29' \
'asyncpg<1.0.0,>=0.29.0' \
'aiosqlite>=0.20.0,<1.0.0' \
'pytz<2025.0,>=2024.1' \
'python-dateutil<3.0.0.0,>=2.9.0.post0' \
'loguru>=0.7.3' \
'cachetools>=5.5.1' \
'jinja2>=3.1.6' \
'dataclasses-json>=0.6.7' \
'psutil>=7.0.0' \
'uvicorn-worker>=0.3.0' \
'python-multipart>=0.0.20' \
'requests>=2.32.4' \
'httpx[socks]>=0.28.1'
实测回显(安装输出较长,用 pip list 验证关键包版本):
/opt/beaverhabits/.venv/bin/pip list | grep -iE 'nicegui|gunicorn|sqlalchemy|uvicorn '
实测回显:
fastapi-users-db-sqlalchemy 7.0.0
gunicorn 26.2.0
nicegui 3.18.0
SQLAlchemy 2.0.55
uvicorn 0.54.0
💡 说明:
uvicorn-worker会自动带入 gunicorn(它是 gunicorn 的 worker 实现),所以无需单独安装 gunicorn;asyncpg是 PostgreSQL 驱动,默认 SQLite 存储用不到但pyproject.toml声明了它,保持与官方一致以免后续切换存储时缺依赖。
5.4 启动验证
先手工启动一次确认能跑通(激活 venv 后走官方 start.sh prd):
cd /opt/beaverhabits
export PATH=/opt/beaverhabits/.venv/bin:$PATH
ENV=production nohup ./start.sh prd > /tmp/beaver.log 2>&1 &
sleep 12
head -5 /tmp/beaver.log
实测回显:
Starting Uvicorn server in production mode...
[2026-10-22 16:49:29 +0000] [5302] [INFO] Starting gunicorn 26.2.0
[2026-10-22 16:49:29 +0000] [5302] [INFO] Listening at: http://0.0.0.0:8080 (5302)
[2026-10-22 16:49:29 +0000] [5302] [INFO] Using worker: uvicorn_worker.UvicornWorker
[2026-10-22 16:49:29 +0000] [5302] [INFO] Booting worker with pid: 5303
⚠️ 注意:
./start.sh prd必须在 venv 已激活(或 PATH 已包含.venv/bin)的前提下执行,否则脚本里的gunicorn找不到命令直接退出(line 17: gunicorn: command not found,实测复现;官方 Dockerfile 同样通过 PATH 注入 venv 解决)。
HTTP 验证(该测试环境无 curl 时可用 python 内置库验证,效果等价):
/opt/beaverhabits/.venv/bin/python -c "import urllib.request; print('HTTP', urllib.request.urlopen('http://127.0.0.1:8080/login', timeout=10).status)"
实测回显:
HTTP 200
ls -la /opt/beaverhabits/.user/
实测回显:
total 104
drwxr-xr-x 2 root root 4096 Oct 22 16:49 .
drwxr-xr-x 13 root root 4096 Oct 22 16:49 ..
-rw-r--r-- 1 root root 94208 Oct 22 16:49 habits.db
5.5 systemd 托管
停掉手工进程,改用 systemd 托管(单元内容与方案 A 完全一致,直接复用):
pkill -x gunicorn
cat > /etc/systemd/system/beaverhabits.service <<'EOF'
[Unit]
Description=Beaver Habit Tracker (BeaverHabits)
After=network.target
[Service]
Type=simple
User=beaver
Group=beaver
WorkingDirectory=/opt/beaverhabits
Environment=ENV=production
Environment=NICEGUI_STORAGE_PATH=/opt/beaverhabits/.user/.nicegui
ExecStart=/opt/beaverhabits/.venv/bin/gunicorn beaverhabits.main:app --bind 0.0.0.0:8080 -w 1 -k uvicorn_worker.UvicornWorker --max-requests 10000 --log-level info
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
useradd -r -s /usr/sbin/nologin beaver 2>/dev/null || true
mkdir -p /home/beaver
chown -R beaver:beaver /opt/beaverhabits /home/beaver
systemctl daemon-reload
systemctl enable beaverhabits
systemctl start beaverhabits
5.6 验证
systemctl is-active beaverhabits
实测回显:
active
curl -si --max-time 10 http://127.0.0.1:8080/login | head -3
实测回显:
HTTP/1.1 200 OK
date: Thu, 22 Oct 2026 16:49:55 GMT
server: uvicorn
六、方案对比与选择建议
| 维度 | 方案 A:uv 工具链 | 方案 B:pip + venv |
|---|---|---|
| 官方推荐度 | 官方 README 与 Dockerfile 同款构建路径 | 备选,仅依赖 pyproject 声明 |
| 依赖版本 | 按 uv.lock 锁定(nicegui==3.13.0 等,与官方镜像一致) | 按范围解析到最新兼容版(实测 nicegui==3.18.0) |
| 可复现性 | 高:锁定文件精确复现 | 中:随 PyPI 新版本漂移 |
| 额外工具 | 需安装 uv 二进制 | 仅系统 Python + venv,无额外工具 |
| 依赖获取 | uv 全局缓存,重复安装快 | 每台机器独立下载 |
| 适用场景 | 常规联网服务器,追求与官方构建一致 | 受管控环境不便装 uv、或已标准化 pip 工作流 |
| systemd/服务形态 | 完全相同(同一单元文件) | 完全相同 |
选择建议:能联网且允许装 uv,选方案 A——锁定版本带来的可复现性对升级与回滚都更友好(重装即复现);对工具链有约束的服务器选方案 B,功能完全等价。两方案的升级操作见第八章。
七、配置说明
两种方案的配置方式完全一致:BeaverHabits 使用 pydantic-settings 管理配置,支持「环境变量 + 仓库根目录 .env 文件」两种来源(configs.py 通过 dotenv.load_dotenv() 自动读取 .env)。
- 最小生产配置:在
/opt/beaverhabits/.env写入(文件属主设为 beaver):
cat > /opt/beaverhabits/.env <<'EOF'
ENV=production
TIME_ZONE=Asia/Shanghai
JWT_SECRET=q1w2e3r4
EOF
chown beaver:beaver /opt/beaverhabits/.env
chmod 600 /opt/beaverhabits/.env
配置项解读:
ENV=production:与 systemd 的Environment=等效(环境变量优先级高于.env,二者留一处即可);TIME_ZONE=Asia/Shanghai:为所有用户固定打卡日期的判定时区(默认跟随浏览器时区,服务器场景建议固定,无效值会启动失败,实测见本专栏《配置参数详解》);JWT_SECRET=q1w2e3r4:登录令牌签名密钥,默认值是公开的SECRET,必须更换(示例值仅演示格式,生产请用随机长串,如openssl rand -hex 32生成)。
-
数据存储位置:全部数据在
/opt/beaverhabits/.user/(SQLite 库habits.db与浏览器端存储.nicegui/),备份与迁移只需处理该目录;存储后端可用HABITS_STORAGE切换(默认DATABASE),完整参数说明见本专栏《Beaver Habit Tracker v0.10.0 配置参数详解》。 -
修改监听端口:改 systemd 单元中
--bind 0.0.0.0:8080为目标端口后systemctl daemon-reload && systemctl restart beaverhabits。 -
防火墙放行(如启用 ufw):
ufw allow 8080/tcp
实测回显:
Rules updated
Rules updated (v6)
八、升级与多版本管理
升级到新版本(以未来发布 v0.11.0 为例,操作形态与实测过的标签切换一致):
cd /opt/beaverhabits
systemctl stop beaverhabits
git fetch --tags
git checkout v0.11.0
uv sync --frozen --no-dev --no-install-project --python /usr/bin/python3.12
systemctl start beaverhabits
(方案 B 环境把 uv sync 一行替换为 5.3 的 pip install 命令即可。)升级前建议备份:cp -a /opt/beaverhabits/.user /opt/beaverhabits/.user.bak-$(date +%F)。
验证升级结果:
git -C /opt/beaverhabits log --oneline -1
实测回显(v0.10.0 时点):
4b3bc6d Fix bare except: patterns in Python files (#217)
systemctl is-active beaverhabits
curl -si --max-time 10 http://127.0.0.1:8080/login | head -1
实测回显:
active
HTTP/1.1 200 OK
降级:与升级同构——git checkout v0.9.1 后重跑依赖安装并重启服务;数据目录向后兼容(v0.x 系列内无破坏性 schema 变更记录,跨大版本降级前务必先备份 .user/ 并核对官方 Release Notes)。
多版本并存:源码安装天然支持多实例——将不同标签克隆到独立目录(如 /opt/beaverhabits-0.9.1、/opt/beaverhabits-0.10.0),各自执行依赖安装,复制 systemd 单元文件并修改 Description、WorkingDirectory、ExecStart 与 --bind 端口(如 8081),daemon-reload 后即可并行运行、灰度切换。
九、常见问题(FAQ)
Q1:手工执行 ./start.sh prd 报 gunicorn: command not found?
现象(实测):
./start.sh: line 17: gunicorn: command not found
原因:start.sh 直接调用 gunicorn,未激活 venv 时 PATH 中没有该命令。解决:先 source /opt/beaverhabits/.venv/bin/activate 或 export PATH=/opt/beaverhabits/.venv/bin:$PATH 再执行;systemd 方式则无此问题(ExecStart 用绝对路径)。
Q2:systemd 启动失败,状态码 203/EXEC,日志 Permission denied?
现象(实测 journalctl 节选):
beaverhabits.service: Failed to execute /opt/beaverhabits/.venv/bin/gunicorn: Permission denied
beaverhabits.service: Failed at step EXEC spawning /opt/beaverhabits/.venv/bin/gunicorn: Permission denied
beaverhabits.service: Main process exited, code=exited, status=203/EXEC
定位:以 beaver 账号手工执行 /opt/beaverhabits/.venv/bin/gunicorn --version,报 bad interpreter: /opt/beaverhabits/.venv/bin/python: Permission denied——问题不在 gunicorn 本身,而在 venv 的 python 解释器。根因:uv 默认把受管 Python 安装到执行账号家目录(root 时为 /root/.local/share/uv/python/),目录权限 0700,服务账号 beaver 无法访问。解决:按 4.4 安装系统级 Python 3.12,删除旧 venv 并用 --python /usr/bin/python3.12 重建:
rm -rf /opt/beaverhabits/.venv
cd /opt/beaverhabits
uv sync --frozen --no-dev --no-install-project --python /usr/bin/python3.12
chown -R beaver:beaver /opt/beaverhabits
systemctl restart beaverhabits
实测重启后 systemctl is-active 返回 active,问题消失。
Q3:日志出现 Control server error: [Errno 13] Permission denied: '/home/beaver'?
现象(实测):服务正常 active、HTTP 正常,但 journalctl 有该 ERROR 行。原因:gunicorn 会在用户家目录创建控制套接字目录 .gunicorn/,useradd -r 创建的系统账号默认没有家目录。解决:
mkdir -p /home/beaver
chown beaver:beaver /home/beaver
systemctl restart beaverhabits
实测重启后日志中该告警消失,仅剩正常启动行。属良性告警(不影响服务),但建议消除以免排查其他问题时被干扰。
Q4:设置了 TIME_ZONE 后服务起不来?
现象(实测,TIME_ZONE=Bad/Zone 时 gunicorn worker 退出):
Value error, Invalid TIME_ZONE 'Bad/Zone'. Must be a valid IANA timezone name (e.g. 'America/New_York', 'Europe/London', 'Asia/Tokyo'). [type=value_error, input_value='Bad/Zone', input_type=str]
[ERROR] Worker (pid:2416) exited with code 3.
[ERROR] Reason: Worker failed to boot.
解决:换成合法 IANA 时区名(如 Asia/Shanghai、UTC),systemctl restart beaverhabits。BeaverHabits 启动时用 pydantic 严格校验该值,拼错即拒绝启动——这是特性而非缺陷,能第一时间暴露配置笔误。
Q5:端口被占用导致启动失败?
排查:ss -ltnp | grep 8080 找到占用进程;若是其他服务,改 systemd 单元中 --bind 端口并 daemon-reload + restart;浏览器访问记得同步改端口。
Q6:注册/登录页打不开或浏览器访问超时?
依次检查:systemctl is-active beaverhabits(服务状态)→ curl -si http://127.0.0.1:8080/login(本机连通性,区分服务问题与网络问题)→ 服务器安全组/防火墙是否放行 8080 → 云服务商控制台安全规则。本机 curl 通而外网不通,基本可定位在防火墙/安全组层。
Q7:如何备份数据?
整目录拷贝即可:cp -a /opt/beaverhabits/.user /backup/beaver-$(date +%F)。应用还内置每日自动备份调度(ENABLE_DAILY_BACKUP=true,间隔 DAILY_BACKUP_INTERVAL 默认 86400 秒),开启后由应用自行在 .user/ 内生成备份,细节见本专栏 《Beaver Habit Tracker v0.10.0 配置参数详解》。
十、卸载与清理
完整卸载(按安装路径逆序执行):
systemctl stop beaverhabits
systemctl disable beaverhabits
实测回显(disable):
Removed "/etc/systemd/system/multi-user.target.wants/beaverhabits.service".
rm -f /etc/systemd/system/beaverhabits.service
systemctl daemon-reload
rm -rf /opt/beaverhabits /home/beaver
userdel beaver
如不再需要 uv 与 Python 3.12,可一并清理:rm -f /usr/local/bin/uv && rm -rf /root/.local/bin/uv /root/.local/share/uv;apt-get purge -y python3.12 && add-apt-repository -y --remove ppa:deadsnakes/ppa。卸载前如需保留数据,先备份 /opt/beaverhabits/.user/。
十一、参考链接
- 官方仓库与安装文档:
https://github.com/daya0576/beaverhabits(README Self-Hosting 节) - uv 官方文档:
https://docs.astral.sh/uv/ - deadsnakes PPA:
https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa - 版本发布:
https://github.com/daya0576/beaverhabits/releases - 选型背景:本专栏《Beaver Habit Tracker v0.10.0 介绍与选型指南》(https://www.quzuo.net/document/jGfcEORzLK3h)
- 容器化部署:本专栏《Beaver Habit Tracker v0.10.0 Docker Compose 部署指南》
- 配置参数:本专栏《Beaver Habit Tracker v0.10.0 配置参数详解》
- API 调用:本专栏《Beaver Habit Tracker v0.10.0 API 使用详解》