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 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 / Compose | Docker 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)。重新登录取新令牌即可。
十二、参考链接
- 官方安装文档(Dockerless 的 npm scripts 用法):仓库
docs/install/(https://github.com/intri-in/manage-my-damn-life-nextjs) - Sequelize CLI 手册:https://github.com/sequelize/cli
- mysqldump 文档:https://dev.mysql.com/doc/refman/8.4/en/mysqldump.html
- 站内:《Manage My Damn Life 介绍与选型指南》、《Manage My Damn Life Docker Compose 部署指南》、《Manage My Damn Life 0.10.0 配置参数详解》