Manage My Damn Life 0.10.0 常用 CLI 命令与工具详解

Manage My Damn Life(MMDL)v0.10.0 运维命令行全景:Docker Compose 栈启停/日志/重建、Sequelize CLI 迁移状态与执行(14 条全 up 实测)、npm scripts 清单、curl API 健康检查与鉴权头、mysql 客户端数据面查询与 mysqldump 备份、openssl 辅助命令,全部实测回显(2026-11-02)

Manage My Damn LifeManage My Damn Life自托管DockerMySQLCalDAV2026/11/02

Manage My Damn Life 0.10.0 常用 CLI 命令与工具详解

目标:把 Manage My Damn Life(MMDL)v0.10.0 日常运维要用的命令行工具逐个讲透:Docker Compose 栈运维、Sequelize CLI 数据库迁移、npm scripts、curl API 健康检查、mysql 客户端数据面查询与备份、openssl 辅助命令。本文所有命令与输出均为真实环境实测回显逐行照抄(2026-11-02,Ubuntu 24.04.5 + Docker 29.9.2 + Compose v5.6.1,MMDL 0.10.0 + MySQL 8.4.13 + Radicale 3.7.6,栈搭建见 《Manage My Damn Life Docker Compose 部署指南》)。

一、环境信息

项目值
宿主Ubuntu 24.04.5 LTS(Noble),x86_64,内核 7.0.0-38-generic
Docker / ComposeDocker version 29.9.2, build a82e528 / Docker Compose version v5.6.1
应用容器manage-my-damn-life-0100-stack-app-1(intriin/mmdl:latest = 0.10.0,Next.js 15.5.25,Node v20.10.0,npm 10.2.3)
数据库容器manage-my-damn-life-0100-stack-db-1(mysql:8.4 = 8.4.13)
CalDAV 容器manage-my-damn-life-0100-stack-caldav-1(tomsquest/docker-radicale:3.7.6.0)
访问入口http://localhost:8151/(MMDL)、http://localhost:8153/(Radicale)
演示账号MMDL admin / q1w2e3r4;MySQL mmdl / q1w2e3r4(库 mmdl)
工作目录compose 命令一律在栈目录(本文记作 /opt/mmdl/stack)执行

💡 说明:MMDL 没有自带的独立 CLI 程序——它的"命令行面"由四部分组成:Docker Compose(服务生命周期)、Sequelize CLI(数据库迁移,镜像内置)、HTTP API + curl(功能与健康检查)、mysql 客户端(数据面)。本文按此四条线展开。

二、工具概览

工具位置用途版本实测
docker compose宿主栈启停、日志、进入容器、重建v5.6.1
sequelize-cli应用容器 /app数据库迁移与状态检查CLI 6.6.5 / ORM 6.37.8 / Node 20.10.0
npm run应用容器 /app迁移脚本入口(migrate 族)npm 10.2.3
curl宿主API 健康检查与功能验证8.x
mysql 客户端数据库容器表结构/数据查询、mysqldump 备份8.4.13
openssl宿主生成 htpasswd、随机密钥系统自带

三、前置条件

  • 栈已按部署篇建成且 /api/install/check 返回 {"success":true,"data":{"message":""}};
  • 宿主可用 docker 命令(当前用户有 docker 权限);
  • API 类命令需先取得鉴权令牌(见 7.2);
  • 本文示例端口 8151/8153 与容器名按部署篇栈命名,替换到你的环境时对应修改。

四、Docker Compose 栈运维命令

4.1 查看栈状态:docker compose ps

cd /opt/mmdl/stack && docker compose ps

实测回显:

NAME                                      IMAGE                               COMMAND                  SERVICE   CREATED         STATUS                  PORTS
manage-my-damn-life-0100-stack-app-1      intriin/mmdl:latest                 "docker-entrypoint.s…"   app       8 minutes ago   Up Less than a second   0.0.0.0:8151->3000/tcp, [::]:8151->3000/tcp

解读:STATUS 列 Up 即存活;Radicale 服务带健康检查,正常态显示 Up (healthy)。只看某个服务:docker compose ps app。

4.2 查看日志:docker compose logs

# 最近 5 行(持续跟踪把 --tail 5 换成 -f)
docker compose logs --tail 5 app

实测回显:

app-1  |    - Network:      http://d047047adda1:3000
app-1  |
app-1  |  ✓ Starting...
app-1  |  ✓ Ready in 195ms
app-1  | checkIfCalendarURLinCaldavAccount_GetID calendar_id 1

末行是应用处理一次事件接口调用的运行时日志——MMDL 的业务日志直接打到 stdout,排障先看 logs app,数据库问题看 logs db。

4.3 配置改动生效:docker compose up -d

# 修改 .env.local 后重建应用容器(restart 不重读 env_file)
docker compose up -d app

实测回显:

 Container manage-my-damn-life-0100-stack-app-1 Starting
 Container manage-my-damn-life-0100-stack-app-1 Started

4.4 重启与单服务启停

docker compose restart app

实测回显:

 Container manage-my-damn-life-0100-stack-app-1 Restarting
 Container manage-my-damn-life-0100-stack-app-1 Started
docker compose stop app && docker compose start app

实测回显:

 Container manage-my-damn-life-0100-stack-app-1 Stopping
 Container manage-my-damn-life-0100-stack-app-1 Stopped
 Container manage-my-damn-life-0100-stack-app-1 Starting
 Container manage-my-damn-life-0100-stack-app-1 Started

4.5 进入容器:docker compose exec

# 查看应用运行时版本
docker compose exec app node -v && docker compose exec app npm -v

实测回显:

v20.10.0
10.2.3
# 进数据库容器起交互式 mysql
docker compose exec db mysql -ummdl -pq1w2e3r4 mmdl

4.6 全栈停止:docker compose down

docker compose down

实测回显:

 Container manage-my-damn-life-0100-stack-app-1 Stopping
 Container manage-my-damn-life-0100-stack-caldav-1 Stopping
 Container manage-my-damn-life-0100-stack-app-1 Stopped
 Container manage-my-damn-life-0100-stack-app-1 Removing
 Container manage-my-damn-life-0100-stack-caldav-1 Stopped
 Container manage-my-damn-life-0100-stack-caldav-1 Removing
 Container manage-my-damn-life-0100-stack-app-1 Removed
 Container manage-my-damn-life-0100-stack-db-1 Stopping
 Container manage-my-damn-life-0100-stack-caldav-1 Removed
 Container manage-my-damn-life-0100-stack-db-1 Stopped
 Container manage-my-damn-life-0100-stack-db-1 Removing
 Container manage-my-damn-life-0100-stack-db-1 Removed
 Network manage-my-damn-life-0100-stack_app-tier Removing
 Network manage-my-damn-life-0100-stack_app-tier Removed

⚠️ 注意:down 保留 bind mount 数据目录;不要对带命名卷的栈随手用 down -v。重新拉起用 docker compose up -d。

五、Sequelize CLI 迁移命令(应用容器内)

MMDL 的数据库结构由 Sequelize 迁移管理(官方 Dockerless 安装文档的 npm run migrate 即封装此工具)。生产镜像内置 sequelize-cli,可在应用容器内直接调用。

5.1 版本与自检

docker compose exec app sh -c "cd /app && npx sequelize-cli --version 2>&1"

实测回显:

Sequelize CLI [Node: 20.10.0, CLI: 6.6.5, ORM: 6.37.8]

6.6.5

5.2 迁移状态:db:migrate:status

升级或排障前后必查。--env local 对应 config/config.js 的 local 段(读 DB_* 环境变量):

docker compose exec app sh -c "cd /app && npx sequelize-cli db:migrate:status --env local 2>&1"

实测回显:

Sequelize CLI [Node: 20.10.0, CLI: 6.6.5, ORM: 6.37.8]

Loaded configuration file "config/config.js".
Using environment "local".
up 20230728075614-first_migration.js
up 20230730083903-users-add-columns-nextAuth-v-0.3.0.js
up 20230730093908-create-session.js
up 20230730094838-create-account.js
up 20250505065245-create-templates.js
up 20250523111400-nextAuthmigrations.js
up 202506071310-webcalMigrations.js
up 202507141012-webcalEventTableMigration.js
up 202603261553-caldavOAuthMigrations.js
up 20260408-columnSizeIncrease-caldav_accounts.js
up 20260408-columnSizeIncrease-calendar_events.js
up 20260408-columnSizeIncrease-calendars.js
up 20260408-columnSizeIncrease-users.js
up 20260527-addColumnstoCaldavAccounts.js

解读:14 条迁移全部 up 即库结构与当前镜像版本一致;出现 down 行说明有迁移未执行(升级镜像后需跑 5.3)。

迁移文件清单(ls /app/migrations)与状态一一对应,节选实测:

20230728075614-first_migration.js
20230730083903-users-add-columns-nextAuth-v-0.3.0.js
...
20260527-addColumnstoCaldavAccounts.js

(输出节选(实测首尾),完整 14 行与 5.2 状态列表同名同序。)

5.3 执行迁移:db:migrate

新装(未用 Web /install 时)或升级镜像后补迁移:

docker compose exec app sh -c "cd /app && npx sequelize-cli db:migrate --env local 2>&1 | tail -4"

实测回显(已全 up 的环境重复执行,无新迁移、静默成功):

Sequelize CLI [Node: 20.10.0, CLI: 6.6.5, ORM: 6.37.8]

Loaded configuration file "config/config.js".
Using environment "local".

sqlite 方言的迁移(--env sqlite,DB_NAME 当文件路径)实测见配置篇 5.1,尾部三条 migrated 成功回显。

5.4 回滚迁移:db:migrate:undo(高危,未实测)

# 回滚最近一条迁移(破坏性!本文环境未执行,仅给出命令形态)
npx sequelize-cli db:migrate:undo --env local

⚠️ 注意:undo 会真实删除列/表(如最近一条 addColumnstoCaldavAccounts 回滚即丢列及其数据),生产严禁随手执行;确需回滚先完成 8.4 的 mysqldump 全量备份。npm scripts 里的 undo-migrate / undo-migrate-sqlite 是同一命令的封装(见第六节)。

六、npm scripts(应用容器内)

6.1 脚本清单

docker compose exec app sh -c "cd /app && npm run 2>&1 | head -30"

实测回显:

Lifecycle scripts included in manage-my-damn-life-nextjs@0.10.0:
  start
    next start

available via `npm run-script`:
  dev
    next dev
  build
    next build
  lint
    next lint
  migrate
    npx sequelize-cli db:migrate --env local
  migrate-sqlite
    npx sequelize-cli db:migrate --env sqlite
  undo-migrate
    npx sequelize-cli db:migrate:undo --env local
  undo-migrate-sqlite
    npx sequelize-cli db:migrate:undo --env sqlite
  cypress
    cypress open

6.2 生产镜像内可用的脚本

官方 Docker 镜像的启动命令是 node server.js(Next.js standalone 产物),不是 next start,因此生产容器内实用的是迁移族四个脚本:

# 与 5.3 等价的官方推荐写法
docker compose exec app sh -c "cd /app && npm run migrate"

dev / build / lint / cypress 面向源码开发(Dockerless 安装路线:git clone → npm install → npm run migrate → npm run build → npm run start),生产运行镜像内无源码依赖,不要执行。

七、curl API 健康检查与运维

MMDL 全部功能走 HTTP API(/api/ 前缀),curl 即可巡检与操作。

7.1 安装状态健康检查(无需鉴权)

curl -s http://localhost:8151/api/install/check

实测回显(已安装):

{"success":true,"data":{"message":""}}

未初始化时返回 {"success":false,"data":{"message":"NOT_INSTALLED"}}。此接口可作监控探针:非 200 或 success:false 即告警。

7.2 登录取令牌与鉴权头生成

curl -s -X POST http://localhost:8151/api/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"q1w2e3r4"}'

实测回显(节选,userhash/ssid 为 128 位十六进制串):

{"success":"true","data":{"message":{"userhash":"c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec","ssid":"afc1bfbf9eeb6784650b4131506af8e57f91b02ddc0dd29dff6d40420c33472abaa176eff374084e9e2b6d3d7593d04c92a31776217c1c62a74f2e5ebbbee460"}}}

鉴权头 = Basic + base64(userhash:ssid)(明文直塞会返回 PLEASE_LOGIN):

B=$(printf '%s' "<userhash>:<ssid>" | base64 -w0)

7.3 刷新日历(CalDAV 连通性检查)

curl -s -X GET "http://localhost:8151/api/v2/calendars/refresh" -H "Authorization: Basic $B"

实测回显(节选):

{"version":2,"success":true,"data":{"message":"REFRESH_OK","details":[{"username":"admin","url":"http://caldav:5232","name":"My CalDAV","status":"ok", ... ,"caldav_accounts_id":1,"calendars":[{"displayName":"admin/calendars","url":"http://caldav:5232/admin/calendars/", ... ]}]}}

(输出节选(实测首尾)。details[].status 逐账号给出 CalDAV 连通结果:ok 正常,error 多为密码/AES 密钥问题,见配置篇 5.2。)

7.4 拉取任务列表

curl -s -X GET "http://localhost:8151/api/v2/calendars/events/fetch?caldav_accounts_id=1&ctag=6ac82e7319fa592d19a84c183456bb814b40d37c7df2388fce2cd26096e32ae2&syncToken=http://radicale.org/ns/sync/1c6595839c1fd73dff2a5c96ed3f4f74e295f012d44a2ebb4e6df1995b7f947a&url=http%3A%2F%2Fcaldav%3A5232%2Fadmin%2Fcalendars%2F" \
  -H "Authorization: Basic $B" | grep -o 'SUMMARY:[^\\]*'

实测回显:

SUMMARY:seed task
SUMMARY:Buy groceries
SUMMARY:Buy groceries

ctag/syncToken/url 三参数取自 caldav/register 或本接口上次响应,缺失任一返回 422 INVALID_INPUT。

7.5 Radicale 侧直查(CalDAV 协议面)

# 直接读任务 ICS 原文(Basic 用账号密码,非 MMDL 令牌)
curl -s -u admin:q1w2e3r4 http://localhost:8153/admin/calendars/mmdl-created-0002.ics

实测回显:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//mmdl//EN
BEGIN:VTODO
DTSTAMP:20261101T174643Z
DUE;VALUE=DATE:20261105
PRIORITY:1
STATUS:NEEDS-ACTION
SUMMARY:Buy groceries
UID:mmdl-created-0002
END:VTODO
END:VCALENDAR

用途:区分"MMDL 没拉到"还是"CalDAV 本来就没有"——数据面排障的最终裁判。

八、mysql 客户端数据面查询与备份

8.1 表清单

docker compose exec db mysql -ummdl -pq1w2e3r4 -e "SHOW TABLES;" mmdl

实测回显:

Tables_in_mmdl
SequelizeMeta
accounts
caldav_accounts
calendar_events
calendars
custom_filters
labels
otp_table
sessions
settings
ssid_table
templates
users
verification_tokens
webcal_accounts
webcal_events

16 张表:SequelizeMeta 记迁移历史,users/ssid_table/sessions/otp_table 管认证会话,caldav_accounts/calendars/calendar_events 管 CalDAV 索引,其余为功能表(模板/标签/过滤器/webcal)。

8.2 查 CalDAV 账号(密文形态)

docker compose exec db mysql -ummdl -pq1w2e3r4 mmdl -e "SELECT caldav_accounts_id, username, LEFT(password,45) AS pwd_prefix, authMethod FROM caldav_accounts;"

实测回显:

caldav_accounts_id  username  pwd_prefix                                   authMethod
1                   admin     U2FsdGVkX19iR+SIu9MFNiwAGvhYs4id+EDLsqr4Bnw=  Basic

U2FsdGVkX1 前缀即 AES 密文(OpenSSL salt 格式),明文密码从不落库。

8.3 查会话数

docker compose exec db mysql -ummdl -pq1w2e3r4 mmdl -N -e "SELECT COUNT(*) FROM ssid_table;"

实测回显(MAX_CONCURRENT_LOGINS_ALLOWED=3 稳态):

4

8.4 全量备份:mysqldump

docker compose exec db sh -c "mysqldump -ummdl -pq1w2e3r4 mmdl > /tmp/mmdl-backup.sql; ls -la /tmp/mmdl-backup.sql; grep -c 'CREATE TABLE' /tmp/mmdl-backup.sql"

实测回显:

-rw-r--r-- 1 root root 19739 Nov  1 17:59 /tmp/mmdl-backup.sql
16

16 张表全部进入转储。恢复:docker compose exec -T db mysql -ummdl -pq1w2e3r4 mmdl < mmdl-backup.sql。业务数据本体在 Radicale 侧,备份同时打包 ./data/radicale 目录。

九、openssl 辅助命令

# 生成 Radicale htpasswd 账号(md5crypt/apr1,Radicale 3.7 唯一支持的格式)
printf 'admin:%s\n' "$(openssl passwd -apr1 q1w2e3r4)"

实测回显(salt 随机,每次不同属正常):

admin:$apr1$Ag1dcx3B$6WL8TJa9AJq6s9lNiqEGi0
# 生成 AES_PASSWORD / NEXTAUTH_SECRET 等强随机密钥
openssl rand -base64 32

十、注意事项

  • compose 命令必须在栈目录执行(或 -f 指定文件),否则找不到项目;
  • 改 .env.local 后必须 up -d 重建,restart 不重读 env_file;
  • events/fetch、events/add 的参数(ctag/syncToken/url/calendar_id)会随 CalDAV 端变化失效,报 INVALID_INPUT/挂起时重新走 caldav/register 取新值(部署篇 11.8);
  • mysqldump 含 AES 密文与用户数据,转储文件按机密管理;
  • 生产镜像内不要跑 dev/build/cypress(无源码,必然失败)。

十一、常见问题

11.1 exec 进应用容器找不到 npm 脚本入口?

应用文件(server.js、config/、migrations/、package.json)都在容器内 /app 下,sequelize-cli 与 npm 脚本必须以该目录为工作目录。统一写法:docker compose exec app sh -c "cd /app && npm run migrate"(先 cd /app 再执行,本文所有容器内命令实测均此形态)。

11.2 db:migrate:status 出现 down 行?

镜像升级后迁移未跑。先备份(8.4),再 npx sequelize-cli db:migrate --env local,复查 status 全 up。若迁移报错且库是失败初始化残留(如部署篇 11.2 的 Table 'mysql.user' doesn't exist),先解决数据库本身。

11.3 refresh 返回 status:"error" 但 CalDAV 服务正常?

按序排查:AES_PASSWORD 是否被改动(配置篇 5.2 实测:错密钥必 error,恢复即 ok)→ Radicale 账号密码是否变更 → ADDITIONAL_VALID_CALDAV_URL_LIST 是否仍覆盖该 URL。

11.4 curl 全部接口返回 PLEASE_LOGIN?

鉴权头格式错(必须 Basic base64(userhash:ssid),见 7.2)或令牌被滚动淘汰(并发上限,配置篇 5.5)。重新登录取新令牌即可。

十二、参考链接

Manage My Damn Life 0.10.0 常用 CLI 命令与工具详解 - Quzuo