在 VPS 上用 Docker 部署 Donetick:家务按时做,也能看清上一次是谁做的

部署 Donetick 家务管理,配置家庭账号、重复周期与分工,核对提醒和时区,备份任务与完成记录。

·9 min自托管

“滤芯什么时候换的?”这类事情常常只有做过的人记得。扫地、清理空调滤网、给植物浇水,有的按固定日期,有的应从实际完成那天重新计算。放进普通待办清单以后,每次勾选和下次提醒还需要自己安排,家人之间也容易重复做或都以为别人做过了。

Donetick 可以记录家务、重复周期和完成情况,也能在小组里分配任务。这篇用 Docker 部署一个家庭实例,先录入几件确实需要追踪的事情,再选择周期和分工。系统只能记录人提交的完成信息,任务显示已完成,不代表滤芯、清洁或检查真的达到了标准,具体要求仍要写清楚。

从五件家务开始

第一次不要把整套日常生活全部录进去。选几件容易忘、需要轮换或需要知道上次日期的事,例如换滤芯、清理洗衣机、处理可回收物、擦窗和植物养护。每天本来就能顺手完成的事情,如果没有记录价值,可以暂时不加。

固定星期发生的事适合按到期日排期;做完以后再过一段时间才需要重复的事,适合按完成日期计算。比如周二收垃圾的时间不会因为上周三才做而变成周三;滤芯更换则要结合实际更换时间和产品要求。Donetick 支持两种重复思路,设置时先想清楚自己要哪一种。

小组任务可以安排成员和轮换,历史完成记录有助于判断谁上次做过。分工应该由家人先协商,不能把系统里的数量当作所有劳动的完整记录。一次十分钟的小事和一次两小时的清理,单看完成条数不具有可比性。

准备应用目录和配置文件

服务器已经安装 Docker Engine、Compose 插件,账号有 Docker 权限;Caddy 运行在宿主机。域名示例 chores.example.com 指向这台 VPS。下面使用 SQLite,把数据库放在本地目录,方便小规模实例管理。

mkdir -p /opt/donetick/data /opt/donetick/config
cd /opt/donetick
curl -fL https://raw.githubusercontent.com/donetick/donetick/main/config/selfhosted.yaml -o config/selfhosted.yaml

下载的是项目提供的自建配置。安装时先阅读文件,核对与所选镜像版本对应;长期运行应该固定版本,不要每次更新都重新下载 main 分支的配置覆盖原来的设置。第一次保存后,给文件做一份副本,再编辑正式的 selfhosted.yaml。

配置中的 jwt.secret 要换成随机值,不能保留公开示例。可以在服务器终端生成一个值,写入配置文件,避免截图、复制到聊天记录或提交到公开仓库。

openssl rand -hex 32

server.public_host 改为 https://chores.example.com,server.cors_allow_origins 设置为实际浏览器访问的来源,包含协议和域名。不要把整段 YAML 替换成几个摘录字段,其他默认项仍需要保留。若以后使用移动应用,要按当前客户端要求增加准确的来源,不能为方便直接允许所有来源。

自建配置还有 realtime.allowed_origins,需要和实时连接的实际访问入口一起检查;它与普通请求的 CORS 字段分开。server.serve_swagger 在私人家庭实例中可按需要关闭,email.log_raw_url 则建议设为 false,避免重置密码等链接进入普通日志。关闭日志中的链接以后,需要为账号恢复安排可用的邮件渠道。

把数据卷挂到正确位置

保存为 compose.yaml。DT_ENV=selfhosted 让应用读取对应配置,数据库位置由 DT_SQLITE_PATH 指定。文件名或目录写错时,服务可能按意料之外的配置运行,因此启动后还要从日志和界面验证设置。

services:
  donetick:
    image: donetick/donetick:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:2021:2021"
    volumes:
      - ./data:/donetick-data
      - ./config:/config
    environment:
      DT_ENV: selfhosted
      DT_SQLITE_PATH: /donetick-data/donetick.db
      TZ: Asia/Shanghai
    healthcheck:
      test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:2021/api/v1/health || exit 1"]
      start_period: 1m
      timeout: 5s
      interval: 1m
      retries: 3

首次用当前镜像部署以后,记录摘要,改用经过确认的版本或摘要。健康检查使用项目提供的接口,只能证明应用当前响应,不代表通知、家务周期和恢复流程已经正确。配置文件里有密钥,限制读取范围,并检查容器运行用户仍能读取,不能把目录改成全体用户可写。

docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 donetick
curl -f http://127.0.0.1:2021/api/v1/health

如果配置解析失败,检查缩进、字段层级和文件名。selfhosted.yaml 不是普通说明文档,漏掉一层缩进会改变参数归属。写入数据库失败时,检查宿主机挂载目录、权限和剩余空间;删库重新启动会丢失完成历史,不能作为常规排障方法。

家庭成员进入以后收起注册入口

先通过 SSH 转发访问服务,创建自己的账号和小组。在自己的电脑运行下列命令,替换 SSH 用户和服务器地址,再打开本机 12021 端口。

ssh -N -L 12021:127.0.0.1:2021 [email protected]

先确认小组成员和权限,再让家庭成员分别创建账号并加入。不要共用一个账号,否则完成历史无法清楚区分。成员邀请和注册流程以当前界面为准,完成以后把顶层 is_user_creation_disabled 改为 true,重建容器并用未登录窗口检查创建用户已被限制。

Caddy 运行在宿主机时添加如下站点段,校验后重载。域名开启以后,用 HTTPS 地址重新登录并检查普通请求、实时连接和页面刷新。

chores.example.com {
    reverse_proxy 127.0.0.1:2021
}

代理在容器里时需要共享网络和服务名。若页面加载但操作被跨域拦截,检查 public host、CORS 和 realtime 来源是否与当前域名一致。改域名不能只改 DNS,应用配置里写死的入口也要一起更新。

重复任务要做一次跨周期验证

创建一项临时测试任务,设一个容易观察的周期,完成一次,再看下一次日期是否符合预期。尤其是“按完成日期”和“按原到期日期”的选择,最好用模拟延迟完成验证,不要等几个月后的真实滤芯提醒才发现周期错了。

家务描述写清楚完成标准。例如“清理洗衣机”可以说明需要清哪个部位、采用什么程序,关联的维护材料放在适当位置。不要随手把设备序列号、门锁信息、家庭详细住址写进可以分享的任务中。任务标题够简短,具体步骤放在描述或子任务里。

把“大扫除”拆成厨房、卫生间等几项,能让成员接手时知道还剩什么;拆得过细,又会让一次家务需要点十几个按钮。重复任务的子任务是否按预期重置,需要在第一次完成后检查。界面能够建立嵌套结构,不代表任何层级都适合家庭使用。

如果用轮换分配,先和家人确认规则,再验证完成以后下一次的接手人。有人临时外出,应调整那次任务,而不是用补填完成记录的方式勉强凑平统计。历史应该反映真实提交,备注可以说明代做和特殊情况。

提醒与时区分别检查

容器设置 TZ=Asia/Shanghai,仍要查看应用和客户端的时间显示。创建一个当天到期的小测试任务,对照手机与电脑的日期、到期时间和完成记录。如果显示差了几个小时,先排查时间设置,不要通过改任务时间来抵消差异,那会让其他设备也跟着错。

通知渠道按当前版本支持的方式配置,使用邮件时填写自己的发件服务器和账号,测试一次发送,再验证任务触发。邮箱密码不是登录 Donetick 的密码,服务地址、端口与加密方式也需要成套匹配。没有配好邮件时,不能假定忘记密码后总能收到恢复链接。

实时页面更新与外部提醒也不同。电脑上的列表自动刷新,不代表关掉浏览器后手机会收到通知;安装成快捷方式或 PWA 后,也要检查系统通知权限和后台行为。把自己真正依赖的接收方式测试通,再开始使用重要的维护提醒。

完成记录也要能恢复

本例最主要的数据在 data,配置在 config。如果使用附件或另外配置对象存储,附件位置和恢复方式也要进入备份范围。项目目前对本地照片存储仍有实现状态提示,重要照片应单独确认实际落点,不要假定全在数据库里。

为 SQLite 取得一致副本,可以短暂停止容器后打包整个实例目录。备份成功后重启,打包失败也要恢复服务,再检查错误。

cd /opt/donetick
mkdir -p /opt/backups
docker compose stop donetick
tar -czf "/opt/backups/donetick-$(date +%F-%H%M).tgz" compose.yaml config data
docker compose start donetick

把副本复制到另一处存储,保护其中的密钥和家庭信息。恢复演练用相同镜像版本,在独立目录与不同回环端口启动,暂时不接正式通知渠道。登录后检查成员、任务、重复周期和较早的完成历史;如果使用附件,再下载核对几个样本。

用了一个月后,可以删掉从不看的标签,调整不合理的提醒,把确实有用的任务留下。家务系统应该减少追问和遗忘;记录不需要每件事都做得像项目管理,但滤芯上次何时更换、这周谁负责哪件事,至少可以直接查到。