Crafty Controller 4.11.0 常用 CLI 命令与工具详解

Crafty Controller 4.11.0 命令行工作面全解:main.py 四参数源码行为与 root 拒绝/双实例互斥排障、sqlite3 逐表排查与 .backup 在线备份、logging.json 缺失致日志缺勤实录、自签证书与元数据核验、探活与运行时工具链,全部回显 2026-11-02/03 实测。

Crafty ControllerMinecraft面板PythonSQLite自托管2026/11/03

Crafty Controller 4.11.0 常用 CLI 命令与工具详解

目标:把 Crafty Controller 4.11.0 的命令行工作面讲透——主程序 main.py 的全部启动参数与源码行为、SQLite 数据库的逐表排查与在线备份、8 个日志文件的用途与真实样本、自签证书与元数据文件的核验方法、服务探活与运行时工具链,全部命令与回显为 2026-11-02/03 实测,含 root 拒绝启动、双实例互斥、logging.json 缺失三类排障实录。

一、环境信息

  • 操作系统:Ubuntu 24.04.5 LTS(x86_64),服务运行环境内 Python 3.12.3;
  • 软件版本:Crafty Controller 4.11.0(config/version.json 实测 {"major": 4, "minor": 11, "sub": 0};上游最新稳定版核实过程见《Crafty Controller 介绍与选型指南》);
  • 部署路线:本文沿用本专栏《Crafty Controller Docker Compose 部署指南》的 Compose 部署形态,服务安装根目录 /crafty,程序目录 /crafty/app;
  • 数据文件双视角:config/、logs/、servers/、backups/、import/ 五个目录同时存在于服务环境(/crafty/...)与 compose 目录(./docker/...),是同一份文件,宿主侧可直接用常规工具读写;
  • 数据库:/crafty/app/config/db/crafty.sqlite(即 compose 目录 docker/config/db/crafty.sqlite),WAL 模式;
  • Web 入口:服务监听 8443/HTTPS,宿主侧映射 https://127.0.0.1:8135;管理账号 admin(演示口令 q1w2e3r4);
  • 配置参数含义见《Crafty Controller 4.11.0 配置参数详解》,本文不重复。

💡 说明:本文"服务运行环境"指 Crafty 进程所在的执行环境(进入方式见部署篇),"宿主侧"指 compose 目录所在的 Ubuntu 服务器。两组命令的输入与回显均为实测逐条抄录。

二、工具概览

Crafty Controller 4.11.0 没有独立的 crafty-cli 二进制,命令行能力由六类工具拼成:

类别工具位置用途
主程序 CLIpython3 main.py(-h/-i/-v/-d)服务环境 /crafty启动、调试、会话锁处理
数据库sqlite3 3.45.1宿主侧(服务环境未装该 CLI)逐表排查、在线备份、完整性检查
数据库兜底Python 标准库 sqlite3 模块服务环境 venv 内无 sqlite3 CLI 时的等价查询
日志commander/session/schedule/tornado-access/auth/auth_tracker/audit/cmd_queue 共 8 个 .loglogs/ 目录排障主战场
证书openssl两侧均有自签证书有效期/主体核验
运行时java(OpenJDK 25.0.4)、pip、curl(宿主侧)、ss(宿主侧)服务环境/宿主侧游戏服进程、依赖查看、探活、端口核验

实测服务环境内工具缺口(重要,影响排障路线选择):

$ command -v sqlite3 curl ss netstat lsof git
none of netstat/lsof/ss

即服务运行环境没有 sqlite3/curl/ss/netstat/lsof/git,数据库与网络排查要么用宿主侧工具对着 bind 目录做,要么用服务环境内的 Python 标准库做。本文两种路线都给了实测回显。

三、前置条件

  1. 面板进程以非 root 用户 crafty 运行,实测进程链:
$ ps -ef | grep "[m]ain.py"
root           1       0  0 Nov02 ?        00:00:00 sudo -u crafty bash -c source ./.venv/bin/activate && exec python3 main.py -d -i
crafty        23       1  0 Nov02 ?        00:00:04 python3 main.py -d -i
  1. 主程序对 root 直接运行有硬性拒绝(见 4.4 排障实录),所有 main.py 命令必须在服务环境内切到 crafty 用户执行;
  2. 宿主侧操作数据文件需对 docker/config/db/ 有读权限(文件属主 crafty、组 root,权限 rw-rw-r--);
  3. 数据库排查建议在面板低峰期做;WAL 模式允许并发读,见第五章注意事项。

四、主程序 CLI:python3 main.py

4.1 帮助输出(实测)

main.py 位于安装根 /crafty,argparse 定义在 main.py 第 330 行起。以服务用户执行:

$ cd /crafty && source ./.venv/bin/activate && python3 main.py --help
usage: Crafty Controller - A Server Management System [-h] [-i] [-v] [-d]

options:
  -h, --help     show this help message and exit
  -i, --ignore   Ignore session.lock files
  -v, --verbose  Sets logging level to debug.
  -d, --daemon   Runs Crafty in daemon mode (no prompt)

4.2 参数逐项详解

参数类型行为(源码实测核对)
-h, --help内置打印上方 usage 后退出
-i, --ignorestore_true启动时若存在 config/session.lock 直接删除再继续(helpers.py 的 create_session_file():if ignore and os.path.exists(self.session_file): os.remove(...)),随后写入自己的 pid
-v, --verbosestore_true日志级别设为 DEBUG:logging_config["loggers"][""]["level"] = "DEBUG",且控制台 Console.level = "debug"
-d, --daemonstore_true守护模式,不带交互 prompt

4.3 默认启动参数

服务入口脚本把参数原样透传给 python3 main.py,本实例默认启动参数为 -d -i,启动行实测:

Wrapper | 🚀 Launching crafty with [-d -i]

也就是说线上面板本身就是"守护模式 + 忽略会话锁"起跑的——-i 让每次重启无条件重建 session.lock,这是官方为单实例托管场景做的取舍;手工排障时不要随手加 -i(见 4.5)。

4.4 排障实录一:root 直接运行被拒

以 root 身份跑 python3 main.py --help,usage 一个字都不会打印,实测回显:

$ cd /crafty && .venv/bin/python3 main.py --help
[+] Crafty: 11/03/26 00:12:43 - CRITICAL:	Root detected. Root/Admin access denied. Run Crafty again with non-elevated permissions.
[+] Crafty: 11/03/26 00:12:48 - CRITICAL:	Crafty shutting down. Root/Admin access denied.

源码位置 main.py 37–44 行:helper.check_root() 命中后打印两条 CRITICAL、time.sleep(5),然后 sys.exit(0)。两个坑:

  1. 检查发生在 argparse 之前,所以 --help 也被拦;
  2. 退出码是 0,脚本里用返回码判断"启动成功"会被骗过——要判断成败应 grep Root/Admin access denied。

4.5 排障实录二:双实例互斥(session.lock)

面板在跑时再起第二个实例(不带 -i),实测回显:

$ cd /crafty && sudo -u crafty bash -c "source ./.venv/bin/activate && timeout 40 python3 main.py 2>&1 | tail -8"
    ///////////////////////////////////////////////////////////////////////////
    #          Server Manager / Web Portal for your Minecraft server          #
    #                     Homepage: www.craftycontrol.com                     #
    ///////////////////////////////////////////////////////////////////////////

[+] Crafty: 11/03/26 00:15:50 - CRITICAL:	Another Crafty Controller agent seems to be running...
pid: 23 
started on: 03-11-2026, 00:14:58
$ echo "rc=$?"
rc=1

行为链(create_session_file() 源码核对):读 config/session.lock 取 pid → psutil.pid_exists(pid) 为真 → CRITICAL + logger.critical("Found running crafty process. Exiting.") → sys.exit(1)。若 pid 已不存在(上次崩溃残留的锁),则打印 No process found for pid. Assuming crafty crashed. Deleting stale session.lock 并自动清锁继续——所以崩溃后的陈旧锁不需要人工删,正常重启会自愈;人工删锁只应发生在"确认旧进程已死但锁 JSON 解析失败"的场景(该分支同样会 sys.exit(1),报错文案为 Failed to locate existing session.lock with error: ...)。

session.lock 本体实测(面板在跑时):

$ cat /crafty/app/config/session.lock
{
    "pid": 23,
    "started": "03-11-2026, 00:14:58"
}

五、SQLite 数据库工具:sqlite3

5.1 版本与总表

宿主侧对 bind 目录里的库文件直接操作(服务环境无 sqlite3 CLI,见 5.7 兜底):

$ sqlite3 --version
3.45.1 2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257ccalt1 (64-bit)

$ sqlite3 docker/config/db/crafty.sqlite ".tables"
api_keys            passkey_challenges  server_stats        user_roles
backups             passkey_data        servers             users
crafty_settings     role_servers        totp_data           webhooks
host_stats          roles               totp_recovery
migratehistory      schedules           user_crafty

18 张表,与面板功能面对得上:users/user_roles/roles(账号与权限)、servers(游戏服定义)、server_stats/host_stats(指标时序)、schedules(计划任务)、backups(备份记录)、api_keys/webhooks(自动化)、totp_*/passkey_*(二次认证)、crafty_settings(Web 侧设置)、migratehistory(迁移流水)。

5.2 运行模式与完整性

$ sqlite3 docker/config/db/crafty.sqlite "PRAGMA journal_mode; PRAGMA integrity_check;"
wal
ok

WAL 是面板启动时由 peewee 强制设置的,main.py 建库参数实测源码:

database = peewee.SqliteDatabase(
    helper.db_path,
    pragmas={
        "journal_mode": "wal",
        "cache_size": -1024 * 10,
        "busy_timeout": 5000,  # Allows a wait to hold for up to 5s before dropping.
        "synchronous": 1,  # NORMAL mode, decrease WAL commit interval.
    },
)

busy_timeout 5000 意味着排障脚本撞锁最多等 5 秒;db/ 目录三件套实测:

$ ls -la docker/config/db/
total 836
drwxrwsr-x 2 crafty root   4096 Nov  3 00:14 .
drwxrwsr-x 4 root   root   4096 Nov  3 00:15 ..
-rw-rw-r-- 1 crafty root 765952 Nov  3 00:14 crafty.sqlite
-rw-rw-r-- 1 crafty root  32768 Nov  3 00:15 crafty.sqlite-shm
-rw-rw-r-- 1 crafty root  41232 Nov  3 00:16 crafty.sqlite-wal

⚠️ 备份不要直接 cp 主库文件——WAL 里可能有未合并的写入。用 5.6 的在线备份命令。

5.3 账号与服务器排查(只读)

$ sqlite3 -header -column docker/config/db/crafty.sqlite "SELECT user_id, username, superuser, enabled, last_login FROM users;"
user_id  username  superuser  enabled  last_login
-------  --------  ---------  -------  --------------------------
1        admin     1          1        2026-11-02 21:13:08.274723
2        system    0          0        2026-11-02 21:13:17.639322

$ sqlite3 docker/config/db/crafty.sqlite "SELECT 'servers',COUNT(*) FROM servers UNION ALL SELECT 'api_keys',COUNT(*) FROM api_keys UNION ALL SELECT 'webhooks',COUNT(*) FROM webhooks UNION ALL SELECT 'schedules',COUNT(*) FROM schedules UNION ALL SELECT 'backups',COUNT(*) FROM backups UNION ALL SELECT 'server_stats',COUNT(*) FROM server_stats UNION ALL SELECT 'host_stats',COUNT(*) FROM host_stats UNION ALL SELECT 'migratehistory',COUNT(*) FROM migratehistory;"
servers|0
api_keys|0
webhooks|0
schedules|0
backups|0
server_stats|0
host_stats|273
migratehistory|64

解读:admin 是超级用户(superuser=1);system 是面板内置伪用户(enabled=0,Web 登录名会被它占用,建号时不要用 system);host_stats 273 行是 30 秒一次的宿主指标采样(stats_update_frequency_seconds=30,见配置详解篇),server_stats 为 0 因为还没纳管游戏服;migratehistory 64 条是版本迁移流水:

$ sqlite3 -header -column docker/config/db/crafty.sqlite "SELECT * FROM migratehistory ORDER BY id DESC LIMIT 3;"
id  name                        migrated_at
--  --------------------------  --------------------------
64  20260609_custom_logos       2026-11-02 13:13:04.583974
63  20260604_og_embed           2026-11-02 13:13:04.580812
62  20260216_dashboard_columns  2026-11-02 13:13:04.575276

面板升级后核对"迁移是否跑完"就看这张表的最新条目;启动日志里的对应行是 Starting migrations → There is nothing to migrate(见第六章样本)。

5.4 游戏服定义表结构(servers)

$ sqlite3 docker/config/db/crafty.sqlite "SELECT sql FROM sqlite_master WHERE name='servers';" | head -5
CREATE TABLE "servers" ("server_id" VARCHAR(255) NOT NULL PRIMARY KEY, "created" DATETIME NOT NULL, "server_name" VARCHAR(255) NOT NULL, "path" VARCHAR(255) NOT NULL, "executable" VARCHAR(255) NOT NULL, "log_path" VARCHAR(255) NOT NULL, "execution_command" VARCHAR(255) NOT NULL, "auto_start" INTEGER NOT NULL, "auto_start_delay" INTEGER NOT NULL, "crash_detection" INTEGER NOT NULL, "stop_command" VARCHAR(255) NOT NULL, "executable_update_url" VARCHAR(255) NOT NULL, "server_ip" VARCHAR(255) NOT NULL, "server_port" INTEGER NOT NULL, "logs_delete_after" INTEGER NOT NULL, "type" VARCHAR(255) NOT NULL, "ignored_exits" VARCHAR(255) NOT NULL, "show_status" INTEGER NOT NULL, "created_by" INTEGER NOT NULL, "shutdown_timeout" INTEGER NOT NULL, "app_id" INTEGER, "count_players" INTEGER NOT NULL, "update_watcher" INTEGER NOT NULL)

排障常用点:path(世界目录,必须在 servers/ 挂载内)、execution_command(启动命令)、server_port(对外的 MC 端口,落在 compose 映射的 25500-25510 段内才连得进)。新建/改服走 Web 界面,不要 INSERT 手工造行——server_id 与目录结构、权限组由面板创建流程一起生成。

5.5 Web 侧设置表(crafty_settings)

单行宽表,密钥与外观都在这里面:

$ sqlite3 docker/config/db/crafty.sqlite ".schema crafty_settings"
CREATE TABLE IF NOT EXISTS "crafty_settings" ("id" INTEGER NOT NULL PRIMARY KEY, "secret_api_key" VARCHAR(255) NOT NULL, "login_photo" VARCHAR(255) NOT NULL, "login_opacity" INTEGER NOT NULL, "master_server_dir" VARCHAR(255) NOT NULL, "cookie_secret" VARCHAR(255) NOT NULL, "og_enabled" INTEGER NOT NULL, "og_title" VARCHAR(255) NOT NULL, "og_description" VARCHAR(255) NOT NULL, "og_image" VARCHAR(255) NOT NULL, "og_color" VARCHAR(255) NOT NULL, "logo_full" VARCHAR(255) NOT NULL, "logo_square" VARCHAR(255) NOT NULL);

$ sqlite3 -header -column docker/config/db/crafty.sqlite "SELECT id, master_server_dir, login_opacity, og_enabled, og_title, logo_full FROM crafty_settings;"
id  master_server_dir  login_opacity  og_enabled  og_title  logo_full
--  -----------------  -------------  ----------  --------  ---------
1   /crafty/servers    100            1

注意查询时避开 secret_api_key 与 cookie_secret 两列——它们分别用于 API 签名与会话 cookie 加密,泄露即会话可伪造;排障只需要上面这些非敏感列。

5.6 在线备份与恢复核验

面板在跑时做一致性快照,用 sqlite3 的 .backup 内建命令:

$ sqlite3 docker/config/db/crafty.sqlite ".backup ./backup_demo.sqlite"
$ sqlite3 ./backup_demo.sqlite "PRAGMA integrity_check; SELECT COUNT(*) FROM users;"
ok
2

恢复演练口径:停服 → 把快照替换 crafty.sqlite(同时清掉旧 -shm/-wal)→ 起服,面板会重建 WAL 三件套。生产备份建议 cron 里跑 .backup 后连同 config.json、web/certs/ 一起打包(备份范围与敏感件清单见配置详解篇第九章)。

5.7 兜底路线:服务环境内用 Python 标准库

服务环境没有 sqlite3 CLI,但 venv 的 Python 自带 sqlite3 模块(内置 SQLite 3.45.1),等价查询实测:

$ python3 -c "import sqlite3; print(sqlite3.sqlite_version)"
3.45.1
$ sudo -u crafty python3 -c "import sqlite3; c=sqlite3.connect('/crafty/app/config/db/crafty.sqlite'); print(c.execute('SELECT COUNT(*) FROM users').fetchone()); print(c.execute('SELECT username, superuser FROM users').fetchall())"
(2,)
[('admin', 1), ('system', 0)]

以 crafty 用户操作自己的库文件,权限路线与宿主侧 root 读 bind 目录互为备份,两条都验证可用。

六、日志工具:logs/ 目录 8 个文件

6.1 文件清单与用途

$ ls -la /crafty/logs/
total 52
drwxrwsr-x 2 root   root  4096 Nov  3 00:14 .
drwxrwsrwx 1 crafty root  4096 Nov  3 00:15 ..
-rw-rw-r-- 1 crafty root     0 Nov  2 21:13 audit.log
-rw-r--r-- 1 crafty root     0 Nov  3 00:14 auth.log
-rw-rw-r-- 1 crafty root     2 Nov  3 00:14 auth_tracker.log
-rw-r--r-- 1 crafty root     0 Nov  3 00:14 cmd_queue.log
-rw-rw-r-- 1 crafty root 12553 Nov  3 00:15 commander.log
-rw-r--r-- 1 crafty root  3052 Nov  3 00:15 schedule.log
-rw-r--r-- 1 crafty root 12553 Nov  3 00:15 session.log
-rw-r--r-- 1 crafty root     0 Nov  3 00:14 tornado-access.log
文件记录器用途
commander.log[Crafty]面板主日志:启动序列、迁移、Web 绑定、BigBucket 检查
session.log[Crafty]与主日志同源的第二落点(含异常堆栈)
schedule.log[Schedules]APScheduler 任务流水(指标采集、版本检查、头像刷新)
tornado-access.log[Tornado]HTTP 访问日志,JSON 多行格式,含状态码/路径/来源 IP/耗时
auth.log认证登录/登出/权限事件(有登录动作才写)
auth_tracker.log认证计数登录限流计数器,JSON 字典,空闲时就是 {}
audit.log[Audit]JSON 格式审计流水(需 enable_audit_logging,默认关)
cmd_queue.log命令队列队列化服务器命令的执行记录

6.2 主日志:启动序列样本

$ head -12 /crafty/logs/commander.log
2026-11-03 00:14:58,169 - [Crafty] - INFO     - __main__ - ***** Crafty Controller Started *****
2026-11-03 00:14:58,169 - [Crafty] - INFO     - app.classes.shared.migration - Starting migrations
2026-11-03 00:14:58,172 - [Crafty] - INFO     - app.classes.shared.migration - There is nothing to migrate
2026-11-03 00:14:58,183 - [Crafty] - INFO     - __main__ - Initializing all servers defined
2026-11-03 00:14:58,183 - [Crafty] - INFO     - app.classes.helpers.helpers - SSL Cert File is set to: /crafty/app/config/web/certs/commander.cert.pem
2026-11-03 00:14:58,183 - [Crafty] - INFO     - app.classes.helpers.helpers - SSL Key File is set to: /crafty/app/config/web/certs/commander.key.pem
2026-11-03 00:14:58,183 - [Crafty] - INFO     - app.classes.helpers.helpers - Cert and Key files already exists, not creating them.
2026-11-03 00:14:58,184 - [Crafty] - INFO     - app.classes.web.tornado_handler - Starting Web Server on ports https:8443
2026-11-03 00:14:58,190 - [Crafty] - INFO     - app.classes.web.tornado_handler - https://10.89.62.2:8443 is up and ready for connections.
2026-11-03 00:15:00,701 - [Crafty] - INFO     - app.classes.big_bucket.bigbucket - Checking Big Bucket status
2026-11-03 00:15:02,194 - [Crafty] - INFO     - __main__ - Checking Internet. This may take a minute.
2026-11-03 00:15:03,367 - [Crafty] - ERROR    - app.classes.big_bucket.bigbucket - Unable to connect to big bucket due to error: HTTPSConnectionPool(host='jars.arcadiatech.org', port=443): Read timed out. (read timeout=2)

排障读法:Starting Web Server on ports https:8443 确认监听;最后一行 BigBucket 超时是受限网络访问官方 jar 源失败的典型表现(不影响面板本身,处置见配置详解篇下载源章节与部署篇 FAQ)。

6.3 调度日志:指标采集心跳

$ grep -m3 "Running job" /crafty/logs/schedule.log
2026-11-03 00:15:30,699 - [Schedules] - INFO - Running job "Stats.record_stats (trigger: interval[0:00:30], next run at: 2026-11-03 00:16:00 CST)" (scheduled at 2026-11-03 00:15:30.699226+08:00)

30 秒间隔与 host_stats 行数互相印证(面板起了约 14 分钟,采样 273 行含历史累计)。

6.4 访问日志:JSON 逐请求

对宿主端口打两枪后实测 tornado-access.log 全文:

$ curl -sk -o /dev/null -w "GET / -> %{http_code}\n" https://127.0.0.1:8135/
GET / -> 302
$ curl -sk -o /dev/null -w "GET /login -> %{http_code}\n" https://127.0.0.1:8135/login
GET /login -> 200
$ cat /crafty/logs/tornado-access.log
2026-11-03 00:15:37,683 - [Tornado] - [Access] - INFO - {
    "Status_Code": 302,
    "Method": "GET",
    "URL": "/",
    "Remote_IP": "10.89.62.1",
    "Elapsed_Time": "0.21ms"
}
2026-11-03 00:15:37,699 - [Tornado] - [Access] - INFO - {
    "Status_Code": 200,
    "Method": "GET",
    "URL": "/login",
    "Remote_IP": "10.89.62.1",
    "Elapsed_Time": "3.89ms"
}

每条请求 5 行 JSON,grep -A5 '"URL": "/login"' 是最常用检索。未登录访问受保护路径会被 302 到登录页(见第八章探活)。

6.5 排障实录三:logging.json 缺失导致日志文件"缺勤"

本实例首启后 logs/ 里只有 3 个文件(audit.log 0 字节、auth_tracker.log 2 字节、commander.log 0 字节),session/schedule/tornado-access/auth/cmd_queue 五个文件根本不生成。原因实测核对 main.py 源码:日志器全部由 config/logging.json 的 dictConfig 定义,文件缺失时走 logging.basicConfig(level=DEBUG) 兜底并打印 Unable to read logging config from ...——主日志改走进程 stdout,文件日志器只剩代码里显式 open() 预建的三个。处置(与部署篇 FAQ 10.2 同一路线):

# 从程序目录的出厂配置副本取回 logging.json(连同 motd_format.json)
$ cp /crafty/app/config_original/logging.json /crafty/app/config/logging.json
$ cp /crafty/app/config_original/motd_format.json /crafty/app/config/motd_format.json
# 重启服务(docker compose restart,操作口径见部署篇)
$ ls -la /crafty/app/config/ | grep -E "logging|motd"
-rw-rw-r-- 1 root   root   3326 Nov  3 00:14 logging.json
-rw-rw-r-- 1 root   root    467 Nov  3 00:14 motd_format.json
$ ls /crafty/logs/
audit.log  auth.log  auth_tracker.log  cmd_queue.log  commander.log  schedule.log  session.log  tornado-access.log

8 个文件齐备,主日志开始落盘(commander.log 12553 字节)。结论:日志文件"少了一半"不是坏了,是 logging.json 没了;升级/迁移时把 config 目录整包带上即可避免。

七、证书与元数据文件

7.1 自签 TLS 证书核验

面板首启自签 commander.cert.pem/commander.key.pem(config/web/certs/)。两侧核验命令同一份文件,宿主侧实测:

$ openssl x509 -in docker/config/web/certs/commander.cert.pem -noout -subject -issuer -dates
subject=C = US, ST = Indiana, O = "Arcadia Technology, LLC", OU = Crafty Controller, CN = 729d129f27ab, emailAddress = info@arcadiatech.org
issuer=C = US, ST = Indiana, O = "Arcadia Technology, LLC", OU = Crafty Controller, CN = 729d129f27ab, emailAddress = info@arcadiatech.org
notBefore=Nov  2 13:13:09 2026 GMT
notAfter=Nov  2 13:13:09 2027 GMT

读法:subject=issuer 即自签;CN 取的是运行环境主机名;有效期整一年,到期前面板不会自动续签——生产域名应反代挂正式证书(base_url/use_https 配置见配置详解篇),别指望这张自签证书撑过 2027-11-02。私钥权限实测组内可读(-rw-rw-r-- crafty root),宿主侧排查用 root 即可,无需改权限。

7.2 版本与会话元数据

$ cat /crafty/app/config/version.json
{
  "major": 4,
  "minor": 11,
  "sub": 0
}

version.json 每次启动由入口脚本从程序目录强制刷新(保持与运行版本一致),排障时用它核对"数据目录被哪个版本动过"。session.lock 语义见 4.5。

7.3 初始管理员凭据文件

首启生成的 config/default-creds.txt(权限 rw-rw----,比其它配置文件更严)实测格式:

$ cat /crafty/app/config/default-creds.txt
{
    "username": "admin",
    "password": "<64位随机口令,此处按安全规范省略>",
    "info": "This is NOT where you change your password. This file is only a means to give you a default password."
}

要点:口令只在首次初始化时生效,改密码不写回该文件(info 字段明说);如果希望初始口令可预期,用官方机制在 config 目录预置 default.json(同结构,本实例实测预置 {"username": "admin", "password": "q1w2e3r4"} 后初始账号即为演示账号),首启后删除该文件或开启 delete_default_json 防口令残留。default-creds.txt 属敏感件,备份包加密存放(口径同配置详解篇)。

八、探活与运行时工具链

8.1 HTTP 探活(宿主侧 curl)

$ curl -sk -o /dev/null -w "GET / -> %{http_code} redirect=%{redirect_url}\n" https://127.0.0.1:8135/
GET / -> 302 redirect=https://127.0.0.1:8135/panel/dashboard
$ curl -sk -o /dev/null -w "GET /api/servers -> %{http_code}\n" https://127.0.0.1:8135/api/servers
GET /api/servers -> 302

302 → /panel/dashboard 即面板活着;未带凭据访问 API 路径被 302 甩向登录(401/403 与 302 的差别取决于路径与 XSRF 校验阶段,排障时以 302 为"服务正常、未认证"的默认预期)。

8.2 端口核验(宿主侧 ss)

服务环境无 ss/netstat/lsof,端口面在宿主侧核验:

$ ss -ltn | grep -E "8135|8123|25500"
LISTEN 0      4096         0.0.0.0:8123       0.0.0.0:*
LISTEN 0      4096         0.0.0.0:8135       0.0.0.0:*
LISTEN 0      4096         0.0.0.0:25500      0.0.0.0:*

8135(面板 HTTPS)、8123(Dynmap 通道)、25500-25510(游戏服端口段)分别对应部署篇的三段端口映射。

8.3 游戏服运行时与面板依赖

纳管 Minecraft 服依赖 Java,服务环境实测:

$ java -version
openjdk version "25.0.4" 2026-07-21
OpenJDK Runtime Environment (build 25.0.4+7-1-24.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 25.0.4+7-1-24.04-Ubuntu, mixed mode, sharing)

面板自身依赖以 venv 内实测为准(升级排障对照用):

$ .venv/bin/pip list | grep -Ei "^(tornado|peewee|APScheduler|psutil)"
APScheduler               3.10.4
peewee                    3.13.0
psutil                    5.9.5
tornado                   6.5.4

venv 里另有 httpx、cbor2(passkey/WebAuthn 依赖)等工具入口;不要向该 venv 手工 pip install——升级时程序目录整体替换,手工包会丢,且依赖冲突直接拖垮面板。

九、注意事项

  1. root 不能跑主程序:拒绝逻辑在 argparse 之前且退出码为 0(4.4),脚本化探活别依赖返回码。
  2. -i 不是万能重启开关:它无条件删锁再起,若旧进程没死透就会出现双实例写同一 SQLite——官方默认启动带 -i 是因为托管形态"重启即接管",手工排障时先确认旧 pid 已死再考虑它。
  3. 数据库写操作一律走 Web/API:users.password、crafty_settings.secret_api_key/cookie_secret、migratehistory 都不要手工 UPDATE/DELETE;只读排查随便查。
  4. WAL 三件套同生共死:备份用 .backup(5.6);恢复时旧 -shm/-wal 必须清掉再放新库。
  5. 日志文件数量以 logging.json 为准:缺文件先查配置目录(6.5),别先怀疑面板坏了。
  6. 服务环境工具极简:无 sqlite3/curl/ss/git,排障路线按本文第二/五/八章的"宿主侧 + Python 兜底"两条走。
  7. 敏感文件权限保持默认:default-creds.txt 是 rw-rw----,排查时别把它 chmod 成全局可读。

十、常见问题

Q1:python3 main.py --help 只打出两行 CRITICAL? 你正以 root 跑。切到面板运行用户(本实例为 crafty)再执行,见 4.4。

Q2:手工再起一个实例秒退,日志 Found running crafty process. Exiting.? 双实例互斥保护,属正常。先停掉在跑的实例,或确认 session.lock 里的 pid 已死(陈旧锁面板自己会清,见 4.5)。

Q3:服务环境里 sqlite3 命令不存在? 官方发行形态不带该 CLI。用宿主侧 sqlite3 对着 bind 目录操作(第五章),或服务环境内 Python 标准库兜底(5.7),两条路线均实测可用。

Q4:logs/ 里只有一两个空文件? config/logging.json 缺失,主日志走了 stdout。从 app/config_original/ 补回并重启(6.5 排障实录)。

Q5:auth_tracker.log 内容就一个 {},坏了吗? 没坏。它是登录限流计数器,空闲即空字典;连续登录失败时会写入对应 IP 的计数。

Q6:面板升级后怎么确认数据库迁移完成? SELECT * FROM migratehistory ORDER BY id DESC LIMIT 3; 对照新版本迁移名(5.3),同时 commander.log 里 Starting migrations 后不再出现报错。

Q7:自签证书快到期了,面板会自己续吗? 不会。有效期硬编码一年(7.1),到期前换正式证书走反代,或删掉 web/certs/ 两件套让面板重启时重新自签(客户端会看到新证书告警)。

十一、参考链接

(实测日期 2026-11-02/03;联网链接核实日期 2026-11-02。)

Crafty Controller 4.11.0 常用 CLI 命令与工具详解 - Quzuo