Plane 常用 CLI 命令与运维实战

Plane v1.4.2 运维命令实测:setup.sh 八动作与 backup 全记录(四卷备份清单)、docker compose 起停/日志/单服务矩阵(down 后卷与数据保留验证)、manage.py 子命令全景([db] 组 17 个)与 createsuperuser/wait_for_db/shell/reset_password 实测、pg_dump 备份与 110 表恢复演练、6 条排障实录(2026-10-27)。

PlanePlane项目管理运维Django2026/10/27

Plane 常用 CLI 命令与运维实战

目标:把维护一台 Plane(makeplane/plane,官网 plane.so)自托管实例(社区版 v1.4.2)常用的三套命令入口讲全——官方 setup.sh 安装器、docker compose 编排操作、容器内 Django manage.py 管理命令,并给出备份/恢复的完整实测演练与排障实录。实测环境与部署过程见《Plane Docker Compose 部署实战》(2026-10-27)。

一、命令体系总览

入口形式适用场景
setup.sh官方安装器脚本(交互菜单)安装、启停、升级、日志查看、一键备份
docker compose编排命令(需 -f docker-compose.yaml --env-file plane.env)日常起停、状态、日志、单服务操作
python manage.pyDjango 管理命令(在 api 服务内执行)账号管理、数据修复、健康检查等运营动作

二、setup.sh 安装器

官方安装器(deployments/cli/setup.sh)是交互式菜单,动作集合固定为 8 项(2026-10-27 从 v1.4.2 脚本源码核对):Install、Start、Stop、Restart、Upgrade、View Logs、Backup Data、Exit。

  • install:检测最新 Release 版本号(实测输出 v1.4.2),从 https://github.com/makeplane/plane/releases/download/<版本>/ 下载 docker-compose.yml 与 variables.env 到 plane-app/,完成即提示 Most recent version of Plane is now available for you to use。
  • start/stop/restart:等价于对 plane-app/docker-compose.yaml 执行 up -d/stop/restart,start 会先等数据库迁移(migrator)结束再检查 api 健康,成功后打印 Plane Server started successfully ✅。
  • upgrade:拉取新版本编排与镜像并滚动重建(APP_RELEASE 更新为核心动作)。
  • logs:二级菜单按服务选择(api/web/space/admin/worker/beat-worker/live/migrator/plane-db/plane-redis/plane-mq 等 11 项,源码核对)。
  • backup:见第五章 5.2 节,实测全记录。

⚠️ 注意:setup.sh 内部以当前目录为基准定位 plane-app/,必须在包含 plane-app/ 的目录执行(实测在错误目录跑 backup 会因找不到项目而中断)。

三、docker compose 运维命令矩阵(实测)

以下命令统一在部署目录执行(-f/--env-file 参数省略写法见各代码块,全部为 2026-10-27 实测回显)。

3.1 状态与起停

cd /opt/data/quzuo/tmp/plane/cli/plane-app

# 服务状态(migrator 为一次性迁移服务,Exited(0) 属正常)
docker compose -f docker-compose.yaml --env-file plane.env ps
# NAME                            SERVICE       STATUS
# plane-142-stack-admin-1         admin         Up 21 minutes (healthy)
# plane-142-stack-api-1           api           Up 21 minutes
# ...(共 12 行,含 plane-db/plane-redis/plane-mq/plane-minio/proxy)

# 启动/补齐(up 中断后产生的 Created 状态服务,重跑一次即补启动)
docker compose -f docker-compose.yaml --env-file plane.env up -d

# 停栈并删除服务与网络(不带 -v,全部数据卷保留)
docker compose -f docker-compose.yaml --env-file plane.env down
#  Container plane-142-stack-plane-db-1 Removed
#  Container plane-142-stack-plane-mq-1 Stopped
#  Container plane-142-stack-plane-mq-1 Removing
#  Container plane-142-stack-plane-mq-1 Removed
#  Network plane-142-stack_default Removing
#  Network plane-142-stack_default Removed

down/up 数据保留实测:down 后核对卷仍在(docker volume ls 实测列出 plane-142-stack_pgdata、plane-142-stack_uploads、plane-142-stack_redisdata、plane-142-stack_rabbitmq_data、4 个 logs 卷、2 个 proxy 卷共 11 个),重新 up -d 后:

curl -s -o /dev/null -w 'web HTTP %{http_code}\n' http://localhost:8145/
# web HTTP 200
curl -s -o /dev/null -w '%{http_code}\n' -b cj.txt http://localhost:8145/api/users/me/ -H 'Referer: http://localhost:8145/'
# 200

业务数据与登录会话全部保留(数据库卷未动、SECRET_KEY 未变)。要彻底清数据才需要 down -v(会删除全部 11 个卷,慎用)。

3.2 日志

# 单服务最近日志(实测排障常用)
docker compose -f docker-compose.yaml --env-file plane.env logs api --since 3m
# (逐行 JSON 结构化日志,含 GET 请求、迁移输出、异常记录)

# 跟踪实时日志
docker compose -f docker-compose.yaml --env-file plane.env logs -f api

3.3 单服务执行

# 逻辑备份数据库(见第五章)
docker compose -f docker-compose.yaml --env-file plane.env exec -T -e PGPASSWORD=plane plane-db pg_dump -U plane plane > plane-db-dump.sql

# 在 api 服务里执行 Django 管理命令(见第四章)
docker compose -f docker-compose.yaml --env-file plane.env exec api python manage.py check

四、python manage.py 子命令(实测)

执行方式二选一(-i 仅交互式命令需要):

docker exec plane-142-stack-api-1 python manage.py <子命令>
docker compose -f docker-compose.yaml --env-file plane.env exec api python manage.py <子命令>

4.1 子命令全景

manage.py help 实测列出 Django 内置分组(auth/contenttypes/django/sessions/staticfiles 等)与 Plane 自定义 [db] 组 17 个子命令(2026-10-27 于 v1.4.2 运行实例逐项核对):

[db]
    activate_user
    clear_cache
    copy_issue_comment_to_description
    create_bucket
    create_dummy_data
    create_instance_admin
    create_project_member
    fix_duplicate_sequences
    reactivate_workspace_member
    reset_password
    sync_issue_description_version
    sync_issue_version
    test_email
    update_bucket
    update_deleted_workspace_slug
    wait_for_db
    wait_for_migrations

Django 内置常用项:createsuperuser、changepassword、shell、dbshell、check、dumpdata、loaddata、migrate、showmigrations、collectstatic 等。

4.2 常用命令实测

# 1) 创建平台超级用户(非交互需注入密码环境变量)
docker exec -e DJANGO_SUPERUSER_PASSWORD='plane@admin2026' \
  plane-142-stack-api-1 python manage.py createsuperuser --noinput \
  --email ops@plane.local --username ops-admin
# Superuser created successfully.

# 2) 数据库连通性检查(编排健康检查同款)
docker exec plane-142-stack-api-1 python manage.py wait_for_db
# Database available!

# 3) Django 系统自检
docker exec plane-142-stack-api-1 python manage.py check
# System check identified no issues (0 silenced).

# 4) shell 一行式查询(实例内用户/资产盘点示例)
docker exec plane-142-stack-api-1 python manage.py shell -c \
  "from django.contrib.auth import get_user_model; [print(u.email, u.is_superuser) for u in get_user_model().objects.all()]" 2>/dev/null
# test@plane.local True
# root@plane.local True
# bot_user_af59956c-8f00-4802-a21a-01b7f32c8cac@localhost False
# admin@plane.local False

# 5) 重置某用户密码(交互式输入新密码,需分配 TTY)
docker exec -it plane-142-stack-api-1 python manage.py reset_password test@plane.local

⚠️ reset_password 必须交互执行:实测管道喂入(echo '新密码' | docker exec -i ...)会在读取输入时报 EOFError 退出,改密不生效;必须 -it 进入交互输入。改完用新密码登录验证(实测通过)。

💡 [db] 组其余命令按名称语义即可对号入座:activate_user/reactivate_workspace_member(恢复被停用账号/成员)、clear_cache(清缓存)、create_bucket/update_bucket(对象存储桶操作)、fix_duplicate_sequences(修复重复序列)、sync_issue_version/sync_issue_description_version(描述版本同步)、create_dummy_data(演示数据)等——除上表实测项外未逐一执行,使用前先 --help 看参数。

五、备份与恢复实战

5.1 逻辑备份:pg_dump(实测)

cd /opt/data/quzuo/tmp/plane/cli/plane-app
docker compose -f docker-compose.yaml --env-file plane.env exec -T \
  -e PGPASSWORD=plane plane-db pg_dump -U plane plane > /opt/data/quzuo/tmp/plane/plane-db-dump-test.sql

ls -la /opt/data/quzuo/tmp/plane/plane-db-dump-test.sql
# -rw-r--r-- 1 root root 547163 Oct 27 18:31 plane-db-dump-test.sql
head -4 /opt/data/quzuo/tmp/plane/plane-db-dump-test.sql
# --
# -- PostgreSQL database dump
# --

⚠️ 实测注意:PGPASSWORD 必须显式注入(-e PGPASSWORD=plane),否则 pg_dump/psql 报 fe_sendauth: no password supplied(镜像内 postgres 客户端不读 compose 环境里的密码变量)。-T 去掉伪终端保证重定向文件干净。

5.2 卷备份:setup.sh backup(实测)

在含 plane-app/ 的目录执行一键备份:

cd /opt/data/quzuo/tmp/plane/cli
bash ../setup/setup.sh backup 2>&1 | tail -6
# Copying plane-redis data directory...
# Successfully backed up redisdata data
#
# Backup completed successfully. Backup files are stored in /opt/data/quzuo/tmp/plane/cli/plane-app/backup/20261027-1850

备份产物为四份压缩包(实测清单):

pgdata.tar.gz         9967177 字节   ← 核心业务数据
rabbitmq_data.tar.gz    20334 字节   ← 队列
redisdata.tar.gz          264 字节   ← 缓存
uploads.tar.gz          19948 字节   ← 附件对象存储

💡 实测提示:backup 会临时停栈做物理卷快照,备份完成自动恢复服务;过程中会打印一串 The "SECRET_KEY" variable is not set. Defaulting to a blank string. 告警——这是安装器不带 --env-file 渲染编排导致的噪音,不影响备份结果,但表明该路径只做数据卷快照,不涉及 env 配置。plane.env 与编排文件请单独纳入备份(文件很小,跟配置管理走)。

5.3 恢复演练:pg_dump 导入(实测)

在运行实例上做了完整恢复演练(空库导入 + 数据校验 + 清理):

# 1) 建演练库
docker exec -e PGPASSWORD=plane plane-142-stack-plane-db-1 \
  psql -U plane -d plane -c "CREATE DATABASE restore_test;"
# CREATE DATABASE

# 2) 导入备份(0 错误)
docker exec -i -e PGPASSWORD=plane plane-142-stack-plane-db-1 \
  psql -U plane -d restore_test -q < /opt/data/quzuo/tmp/plane/plane-db-dump-test.sql

# 3) 校验:表数量与用户行数
docker exec -e PGPASSWORD=plane plane-142-stack-plane-db-1 \
  psql -U plane -d restore_test -tAc "SELECT count(*) FROM information_schema.tables WHERE table_schema='public';"
# 110
docker exec -e PGPASSWORD=plane plane-142-stack-plane-db-1 \
  psql -U plane -d restore_test -tAc "SELECT count(*) FROM users;"
# 4

# 4) 清理演练库
docker exec -e PGPASSWORD=plane plane-142-stack-plane-db-1 \
  psql -U plane -d plane -c "DROP DATABASE restore_test;"
# DROP DATABASE

110 张表、4 个用户完整还原,验证了 pg_dump 备份的有效性。业务数据表名以 users(用户)、workspaces_workspace(工作区)等 Django 约定命名,校验时勿凭猜测查表名(实测先查 information_schema.tables 再 count,见排障 Q4)。

5.4 备份策略建议

  • 日常:定时 pg_dump(业务数据主干,体积小、可恢复到任意实例)+ 每日低频 setup.sh backup 卷快照(覆盖附件 uploads 卷);
  • 变更管理:plane.env(含 SECRET_KEY)与 docker-compose.yaml 纳入版本管理——恢复实例时无密钥等于丢全部会话与协作连接;
  • 恢复优先级:先 pg_dump 恢复数据库,再按需用 uploads.tar.gz 还原附件卷(对象文件按 <工作区ID>/<uuid>-<文件名> 组织,与库内 FileAsset 记录对应)。

六、排障实录(命令视角)

Q1:服务停在 Created 状态,页面不通。 up -d 中断的残留。重跑一次 up -d 补齐启动即可(实测 4 个 Created 服务被补启动),详见部署篇 Q1。

Q2:pg_dump 报 fe_sendauth: no password supplied。 -e PGPASSWORD=plane 没加。实测注入后正常导出(5.1 节)。

Q3:manage.py reset_password 管道喂密码报 EOFError。 该命令强制交互读输入(TTY),必须 docker exec -it;改密后新密码登录实测生效(4.2 节注意事项)。

Q4:校验恢复库时报 relation "users_user" does not exist。 v1.4.2 用户表名是 users(非 Django 默认的 users_user)。恢复校验前先查 information_schema.tables 确认表名(5.3 节实测过程)。

Q5:setup.sh backup 刷屏 variable is not set 告警。 安装器渲染编排时不带 --env-file,属噪音;确认备份产物齐全即可(5.2 节实测)。

Q6:更换 SECRET_KEY 后全员 401。 预期行为,重新登录即恢复;轮换窗口安排见配置篇第五章实测。

七、参考链接