RhodeCode 4.27.1 常用 CLI 与运维命令详解

RhodeCode 4.27.1 运维命令实战手册:rccontrol 实例控制、supervisorctl 进程管理(含 4.1.0 tail 崩溃 bug 排障实录)、curl 直调 JSON-RPC API 的用户/权限/仓库全流程(含 grant_user_permission 更名坑)、建库/导入/备份/全文索引/日志排查;全部命令与回显在 Ubuntu 22.04.5 LTS 实测照抄。

RhodeCode版本控制Python 编程Mercurial2026/10/28

RhodeCode 4.27.1 常用 CLI 与运维命令详解

目标:把 RhodeCode Community 4.27.1 在 Ubuntu 22.04.5 LTS 上日常运维要用到的命令一次讲清——rccontrol 实例控制端、supervisorctl 进程管理、curl 直调 JSON-RPC API(用户/权限/仓库)、仓库建库/导入/备份、日志与排障;全部命令与回显均在 Ubuntu 22.04.5 LTS 实测照抄,两条排障实录(API 方法更名坑、supervisorctl tail 崩溃 bug)完整沉淀。安装与环境准备见 《RhodeCode 4.27.1 Ubuntu 22.04 安装指南》,配置文件逐段解析见 《RhodeCode 4.27.1 配置参数详解》,产品定位与选型对比见 《RhodeCode 介绍与选型指南》。

一、环境信息

本文所有命令在以下环境实测(与 《RhodeCode 4.27.1 Ubuntu 22.04 安装指南》 的安装结果一致):

项目值
操作系统Ubuntu 22.04.5 LTS
应用版本RhodeCode Community 4.27.1(含 VCSServer 4.27.1)
控制端rhodecode-control 1.24.4(rccontrol 命令)
运行时Python 2.7.15(RhodeCode 自带运行时,随发行包安装)
数据库PostgreSQL 14(本机 127.0.0.1:5432,库名/用户 rhodecode)
Community 实例community-1,监听 0.0.0.0:10020
VCSServer 实例vcsserver-1,监听 127.0.0.1:10010
supervisor 管理口127.0.0.1:10000(inet_http_server)
仓库存储根/var/opt/rhodecode/repos/
配置目录/root/.rccontrol/(实例)、/root/.rccontrol-profile/(控制端命令)
示例账号admin / q1w2e3r4(管理员)

两处 PATH 提醒(安装篇已说明,本文全部命令假定已生效):

# 控制端命令(rccontrol、supervisorctl)
export PATH=/root/.rccontrol-profile/bin:$PATH
# 实例自带工具(rhodecode-api、rhodecode-index、rc-ishell 等)
export PATH=/root/.rccontrol/community-1/profile/bin:$PATH

二、工具概览

RhodeCode 4.27.1 的运维命令分三组:控制端(/root/.rccontrol-profile/bin/)、实例工具(/root/.rccontrol/community-1/profile/bin/)、API 方法(走 HTTP JSON-RPC)。按用途归类如下。

2.1 服务与进程管理

命令用途常用形式
rccontrol status查看全部实例状态/版本/URLrccontrol status
rccontrol start/stop/restart按 实例名 启停单个实例rccontrol restart community-1
rccontrol self-stop停所有实例 + supervisordrccontrol self-stop
rccontrol upgrade升级指定实例(含 --offline)rccontrol upgrade community-1 --offline
supervisorctl细粒度进程管理(status/tail/pid…)supervisorctl -c /root/.rccontrol/supervisor/supervisord.ini status
rc-upgrade-db升级后执行数据库迁移rc-upgrade-db <实例 ini>

2.2 API 客户端与自动化

命令用途常用形式
curl直调 JSON-RPC 端点 /_admin/api(本文主测)见「四」
rhodecode-api官方 API 命令行客户端(读 /root/.rhoderc)rhodecode-api --instance-name=community-1 get_repos
rhodecode-index构建 Whoosh 全文检索索引rhodecode-index --instance-name=community-1
rhodecode-list-instances列出实例与 API 连接信息rhodecode-list-instances

2.3 仓库与内容维护

命令用途
rhodecode-cleanup-repos清理已归档(软删除)仓库,支持 --older-than/--list-only
rhodecode-cleanup-gists清理已删除 Gist,参数与上同
rhodecode-gist命令行创建/查看 Gist
API rescan_repos仓库目录与数据库不同步时重新扫描登记
tar + pg_dump仓库目录 + 数据库双份备份(见 5.4)

2.4 配置与调试

命令用途
rhodecode-config渲染/更新 ini 配置(--update 改值后需重启实例)
rc-ishell进入 IPython 交互式 shell,可直接调用 Python 层模型
rc-setup-app重新渲染实例配置模板(安装向导用)
rc-add-artifact人工放置归档工件(如 license 文件)

💡 版本说明:4.27.1 的 API 共 88 个方法,可用 get_method(不带参数)一次列出全部方法名,见 4.3。

三、服务与进程管理

RhodeCode 的进程模型是「supervisord 守护 → 两个 supervisor 程序组(community-1、vcsserver-1)→ 各跑一个 gunicorn」。rccontrol 是对 supervisor 的上层封装,日常看状态用 rccontrol,细粒度操作(tail、单进程重启)用 supervisorctl。

3.1 查看整体状态:rccontrol status

$ rccontrol status
RHODECODE CONTROL VERSION: 1.24.4

 - NAME: community-1
 - STATUS: RUNNING
   logs: /root/.rccontrol/community-1/community.log
 - VERSION: 4.27.1 Community
 - VCS: vcsserver-1
 - URL: http://0.0.0.0:10020
 - CONFIG: /root/.rccontrol/community-1/rhodecode.ini

 - NAME: vcsserver-1
 - STATUS: RUNNING
   logs: /root/.rccontrol/vcsserver-1/vcsserver.log
 - VERSION: 4.27.1 VCSServer
 - URL: http://127.0.0.1:10010
 - CONFIG: /root/.rccontrol/vcsserver-1/vcsserver.ini

rccontrol --help 列出的全部子命令(实测回显):

Commands:
  enable-module  Enables additional modules.
  import         Imports your current RhodeCode instance.
  install        Installs the specified RhodeCode application.
  ishell         Starts the specified application iShell interface
  license        Display license information.
  restart        Restarts the specified application instance.
  self-destroy   Completely removes rccontrol and any instances installed
                 on...
  self-init      Initializes rccontrol and supervisord on your server.
  self-stop      Stops all instances and supervisord.
  self-update    Retrieves the latest version information and upgrades...
  start          Starts the specified application instance.
  status         Displays the status of installed application instances.
  stop           Stops the specified application instance.
  uninstall      Uninstalls the specified application instance.
  upgrade        Upgrades the specified application instance.

3.2 supervisorctl 细粒度管理

supervisorctl 必须带 -c 指向 supervisord 配置(认证信息写在配置里,无需手工输密码):

SC="supervisorctl -c /root/.rccontrol/supervisor/supervisord.ini"

查看状态、进程号、supervisor 版本(实测回显):

$ $SC status
community-1:community-1_script   RUNNING   pid 10070, uptime 0:09:35
vcsserver-1:vcsserver-1_script   RUNNING   pid 8813, uptime 0:30:12

$ $SC pid community-1:community-1_script
10070

$ $SC version
4.1.0

💡 程序名必须带组前缀 组名:程序名(community-1:community-1_script)。supervisord 配置里每个实例是 [group:community-1] 包着 [program:community-1_script],裸写 community-1_script 会报 no such process。

重启单个实例(实测:pid 从 10070 变为 10667):

$ $SC restart community-1:community-1_script
community-1:community-1_script: stopped
community-1:community-1_script: started
$ $SC status
community-1:community-1_script   RUNNING   pid 10667, uptime 0:00:07
vcsserver-1:vcsserver-1_script   RUNNING   pid 8813, uptime 0:33:12

stop → start 闭环(实测对 vcsserver-1 操作,STOPPED 状态会显示停止时间):

$ $SC stop vcsserver-1:vcsserver-1_script
vcsserver-1:vcsserver-1_script: stopped
$ $SC status
community-1:community-1_script   RUNNING   pid 10667, uptime 0:02:38
vcsserver-1:vcsserver-1_script   STOPPED   Oct 28 01:55 AM
$ $SC start vcsserver-1:vcsserver-1_script
vcsserver-1:vcsserver-1_script: started
$ $SC status
community-1:community-1_script   RUNNING   pid 10667, uptime 0:02:43
vcsserver-1:vcsserver-1_script   RUNNING   pid 10950, uptime 0:00:05

与 rccontrol 的关系:rccontrol restart community-1 等价于对组做 stop/start,效果相同;差异在 rccontrol self-stop 会把 supervisord 一并停掉(配合 systemd 托管时才是正确的整机停止方式,见安装篇)。

3.3 排障实录一:supervisorctl tail 崩溃(AttributeError)

按 supervisor 官方语法,tail <name> <bytes> 应输出日志尾部,但在本环境(非交互 shell、redirect_stderr=true)实测直接崩溃:

$ $SC tail community-1:community-1_script
error: <type 'exceptions.AttributeError'>, 'NoneType' object has no attribute 'lower': file: /opt/rhodecode/store/4wp0lvs7cb4zaxmpxc6vbiz0cspfa85a-python2.7-supervisor-4.1.0/lib/python2.7/site-packages/supervisor/supervisorctl.py line: 440

$ $SC tail community-1:community-1_script 500
Error: bad channel '500'

两个回显对应两个原因:

  1. 崩溃 bug(line 440):supervisor 4.1.0 的 supervisorctl.py 在 do_tail 入口调用 check_encoding(),其实现为:
def not_all_langs():
    enc = getattr(sys.stdout, 'encoding', '').lower()
    return None if enc.startswith('utf') else sys.stdout.encoding

非交互方式运行(输出经管道/重定向)时 sys.stdout.encoding 是 None 而非空串,getattr 拿到 None 后 .lower() 直接 AttributeError——getattr 的默认值 '' 根本兜不住。这是 supervisor 4.1.0 的已知缺陷,交互 tty 下不触发。

  1. bad channel '500':4.1.0 的 do_tail 参数解析为 tail [-f] <name> [stdout|stderr],第二个位置参数只认 stdout/stderr 通道名;截取字节长度的语法是修饰符 tail -N <name>,不是 tail <name> N(旧版 supervisor 的差异点)。

绕过方案(实测有效):给 stdout 一个编码即可跳过崩溃路径,再按正确语法取日志:

$ export PYTHONIOENCODING=utf-8
$ $SC tail -300 community-1:community-1_script
ode.lib.middleware.request_wrapper] Req[   1] <AuthUser('id:2[admin] ip:127.0.0.1 auth:False')> POST Request to /_admin/api time: 0.0977s [curl/7.81.0], RhodeCode 4.27.1
2026-10-28 01:52:43.560 <10682> INFO  [GNCRN] 127.0.0.1       rqt:0.099070 200 101    "POST:/_admin/api " usr:- "-" "curl/7.81.0"

脚本化运维建议直接读日志文件(见「六」),完全绕开该 bug。

四、用户与权限 API 调用(curl JSON-RPC 实测)

RhodeCode 所有管理操作都有同名 API 方法,端点为 http://<host>:10020/_admin/api,JSON-RPC 2.0 格式,鉴权用 API token(管理员在 Web 界面 Profile → Auth Tokens 生成;实例安装后首个 admin 的 token 也写入了 /root/.rhoderc)。本节全部实测。

4.1 调用骨架与身份验证

curl 请求骨架(auth_token 换成你的 token):

curl -s -X POST http://127.0.0.1:10020/_admin/api \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"auth_token":"<API_TOKEN>","method":"<方法名>","args":{}}'

/root/.rhoderc 内容(rhodecode-api 客户端的默认配置,安装时自动生成):

[instance:community-1]
api_key = c0a9afc7efae6c280f5aa07ea2c8fe1afe9020ec
api_host = http://127.0.0.1:10020

token 错误时的真实回显:

{
    "id": 20,
    "error": "Invalid API KEY",
    "result": null
}

4.2 get_user:查用户与其权限摘要

$ curl -s -X POST http://127.0.0.1:10020/_admin/api \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"auth_token":"c0a9afc7efae6c280f5aa07ea2c8fe1afe9020ec","method":"get_user","args":{"userid":"admin"}}' | python3 -m json.tool

(回显节选——permissions_summary.global 里的 hg.admin 即超级管理员全局权限):

{
    "result": {
        "permissions_summary": {
            "repositories": {
                "demo-project": "repository.admin"
            },
            "global": [
                "hg.admin",
                "hg.create.write_on_repogroup.true"
            ],
            "repository_branches": {},
            "user_groups": {},
            "repositories_groups": {}
        },
        "user_id": 2,
        "last_activity": "2026-10-28T00:58:29.417",
        "email": "admin@rhodecode.local",
        "extern_type": "rhodecode",
        "admin": true,

4.3 get_method:查方法签名与全部方法名

查某个方法的定义(返回该方法的 docstring、参数 schema):

$ curl -s -X POST http://127.0.0.1:10020/_admin/api \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"auth_token":"c0a9afc7efae6c280f5aa07ea2c8fe1afe9020ec","method":"get_method","args":{"name":"create_repo"}}' | python3 -m json.tool

不带 name 参数则列出全部方法名(实测共 88 个,节选):

{
    "result": [
        "changeset_comment",
        "get_locks",
        "show_ip",
        "create_gist",
        "delete_gist",
        "get_gist",
        "get_gists",
        "close_pull_request",
        "comment_pull_request",
        "create_pull_request",
        "get_pull_request",
        "get_pull_request_comments",
        "get_pull_requests",
        "merge_pull_request",
        "update_pull_request",
        "add_field_to_repo",
        "comment_commit",
        "create_repo",
        "delete_repo",
        "fork_repo",
        "get_comment",
        "get_repo",

4.4 create_user:建用户

$ curl -s -X POST http://127.0.0.1:10020/_admin/api \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":5,"auth_token":"c0a9afc7efae6c280f5aa07ea2c8fe1afe9020ec","method":"create_user","args":{"username":"opsuser","password":"q1w2e3r4","email":"opsuser@rhodecode.local","firstname":"Ops","lastname":"User","active":true}}' | python3 -m json.tool

(回显节选——新用户 user_id: 3、admin: false):

{
    "result": {
        "user": {
            "user_id": 3,
            "last_activity": null,
            "email": "opsuser@rhodecode.local",
            "extern_type": "rhodecode",
            "admin": false,

4.5 排障实录二:给仓库授权的正确方法名是 grant_user_permission

按老版本文档给仓库授权,方法名写 grant_user_permission_to_repo,4.27.1 实测直接报错——但报错信息本身就附了近似方法提示,非常有用:

{
    "result": null,
    "error": "No such method: grant_user_permission_to_repo. Similar methods: grant_user_group_permission, grant_user_permission, grant_user_group_permission_to_repo_group, grant_user_permission_to_repo_group, ...",
    "id": 6
}

到实例源码里确认(rhodecode/api/views/repo_api.py,4.27.1 实际代码):

@jsonrpc_method()
def grant_user_permission(request, apiuser, repoid, userid, perm):

即 4.27.1 里"给用户授予仓库权限"的方法名就是 grant_user_permission(签名为 repoid + userid + perm,作用对象是仓库;同理 grant_user_group_permission 是给用户组授仓库权限)。正确调用:

$ curl -s -X POST http://127.0.0.1:10020/_admin/api \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":8,"auth_token":"c0a9afc7efae6c280f5aa07ea2c8fe1afe9020ec","method":"grant_user_permission","args":{"repoid":"ops-d1-demo","userid":"opsuser","perm":"repository.write"}}' | python3 -m json.tool
{
    "result": {
        "success": true,
        "msg": "Granted perm: `repository.write` for user: `opsuser` in repo: `ops-d1-demo`"
    },
    "error": null,
    "id": 8
}

授权后用 get_repo 回查(节选,可见两条权限来源:owner 与显式授权):

        "permissions": [
            {
                "origin": "owner",
                "name": "admin",
                "permission": "repository.admin",
                "type": "user"
            },
            {
                "origin": "permission",

常用仓库级权限取值:repository.none / repository.read / repository.write / repository.admin;撤销用 revoke_user_permission(参数同为 repoid + userid)。

4.6 rhodecode-api 命令行客户端

同一 API 也可用官方 CLI 客户端调用,它读 /root/.rhoderc 里的 api_key/api_host,输出已格式化:

$ rhodecode-api --instance-name=community-1 get_repos
{
  "error": null,
  "id": 7147,
  "result": [
    {
      "clone_uri": "",
      "created_on": "2026-10-28T00:58:19.262",
      "description": "CLI demo repo",
      ...
      "owner": "admin",
      "private": true,
      "repo_id": 1,
      "repo_name": "demo-project",
      "repo_type": "git",
      "url": "http://127.0.0.1:10020/demo-project"
    }
  ]

配套的 rhodecode-list-instances 可列出实例与 API 连接参数(脚本里可用来动态取 key):

$ rhodecode-list-instances
[instance:community-1] - Config only
  API-HOST: http://127.0.0.1:10020
  API-KEY:  c0a9afc7efae6c280f5aa07ea2c8fe1afe9020ec

五、仓库运维(建库 / 导入 / 备份)

5.1 API 建库:create_repo

$ curl -s -X POST http://127.0.0.1:10020/_admin/api \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":4,"auth_token":"c0a9afc7efae6c280f5aa07ea2c8fe1afe9020ec","method":"create_repo","args":{"repo_name":"ops-d1-demo","repo_type":"git","description":"D1 CLI lab repo","private":true}}' | python3 -m json.tool
{
    "result": {
        "task": null,
        "success": true,
        "msg": "Created new repository `ops-d1-demo`"
    },
    "error": null,
    "id": 4
}

重名时报错回显(args.repo_name 冲突检测在前端与 API 双侧生效):

{
    "id": 21,
    "error": {
        "unique_repo_name": "Repository with name `ops-d1-demo` already exists"
    },
    "result": null
}

建库后磁盘上出现对应目录(/var/opt/rhodecode/repos/,下划线替换斜杠):

$ ls /var/opt/rhodecode/repos/
demo-project
ops-d1-demo

5.2 HTTP 导入既有仓库:clone + push

空库可直接 clone 后提交推送(管理员账号走 HTTP Basic 认证,实测完整回显):

$ git clone http://admin:q1w2e3r4@127.0.0.1:10020/ops-d1-demo
Cloning into 'ops-d1-demo'...
warning: You appear to have cloned an empty repository.

$ cd ops-d1-demo
$ git config user.email ops@lab.local && git config user.name ops
$ echo "D1 lab import" > README.md
$ git add . && git commit -m "D1 import commit"
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
$ git push origin master
remote: RhodeCode: open pull request link: http://127.0.0.1:10020/ops-d1-demo/pull-request/new?branch=master
remote: RhodeCode: push completed
To http://127.0.0.1:10020/ops-d1-demo
 * [new branch]      master -> master

导入既有 Git 库的套路:git clone --mirror <旧地址> 后 git push --mirror http://admin:q1w2e3r4@<host>:10020/<库名>;SVN/Mercurial 迁移可先 git svn clone / hg convert 转成 Git 再走同一通道(产品本身也原生托管 hg/svn 库,直接 create_repo 指定 repo_type 后向对应 URL push 即可)。

5.3 仓库目录与数据库对账:rescan_repos

手工往 /var/opt/rhodecode/repos/ 拷贝过裸仓库、或磁盘与登记不一致时,调用 rescan 实测:

$ curl -s -X POST http://127.0.0.1:10020/_admin/api \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":11,"auth_token":"c0a9afc7efae6c280f5aa07ea2c8fe1afe9020ec","method":"rescan_repos","args":{"remove_obsolete":false}}' | python3 -m json.tool
{
    "id": 11,
    "error": null,
    "result": {
        "added": [],
        "removed": []
    }
}

⚠️ remove_obsolete: true 会把数据库中没有登记的磁盘目录直接删除,生产环境先跑 false 看差异。

5.4 备份:pg_dump + tar 双份

数据库(PostgreSQL 14,custom 格式便于 pg_restore --list 抽查):

# postgres 系统用户执行 pg_dump;/root 属主为 root,先落 /tmp 再移入备份目录
$ su postgres -c "pg_dump -d rhodecode -F c -f /tmp/rhodecode-d1.dump"
$ mv /tmp/rhodecode-d1.dump /root/backup/
$ pg_restore --list /root/backup/rhodecode-d1.dump | head -8
;
; Archive created at  2026-10-28 01:52:05 UTC
;     dbname: rhodecode
;     TOC Entries: 486
;     Compression: -1
;     Dump Version: 1.14-0
;     Format: CUSTOM
;     Integer: 4 bytes

仓库目录(版本库文件本体,与数据库各含一半真相——数据库存元数据/PR/权限,repos 目录存版本历史,两者都要备):

$ tar -C /var/opt/rhodecode -czf /root/backup/repos-d1.tar.gz repos
$ ls -la /root/backup/
-rw-r--r-- 1 root     root       4002 Oct 28 01:51 repos-d1.tar.gz
-rw-rw-r-- 1 postgres postgres 192608 Oct 28 01:52 rhodecode-d1.dump
$ tar -tzf /root/backup/repos-d1.tar.gz | head -4
repos/
repos/.rc_gist_store/
repos/.rc_gist_store/1/
repos/.rc_gist_store/1/.hg/

恢复演练要点:先 pg_restore -d rhodecode <dump> 回灌数据库,再把 repos 目录解回 /var/opt/rhodecode/,最后调一次 rescan_repos(5.3)对账。

5.5 全文检索索引:rhodecode-index

Whoosh 索引默认存 %(here)s/data/index(即 /root/.rccontrol/community-1/data/index,search.location 参数,见配置篇)。手工重建索引实测:

$ rhodecode-index --instance-name=community-1 \
    --api-key=c0a9afc7efae6c280f5aa07ea2c8fe1afe9020ec \
    --api-host=http://127.0.0.1:10020
PROCESSED [demo-project] 1/2 repo process limit:-1

FETCH     [ops-d1-demo] repository configuration
FETCH     [ops-d1-demo] repository configuration [done in: 0.068s]
FETCH     [ops-d1-demo] commit info (1000 commits per call. Server reported 1 total commits, process limit is 10000)
          Fetched 1000 commits [1 total][fetch:0001]
FETCH     [ops-d1-demo] commit info [done in: 0.056s]
FETCH     [ops-d1-demo] file tree info (@commit_id: branch:master:`3bed239f`) [1 done in: 0.067s]
FILES     [ops-d1-demo] marked for indexing: 1
FILES     [ops-d1-demo] marked for re-indexing: 0
FILES     [ops-d1-demo] marked for removal: 0
FETCH     [ops-d1-demo] file content info (@path `README.md` @commit_id: `3bed239f`) [1 done in: 0.040s]
PROCESSED [ops-d1-demo] 2/2 repo process limit:-1

>>> FINISHED BUILDING INDEX <<<

定时任务建议(夜间增量):rhodecode-index --instance-name=community-1 --index-update 配 cron;全量重建直接去掉该参数。改了 search_mapping.ini(配置篇有解析)后需全量重建。

5.6 软删除清理:rhodecode-cleanup-repos

Web/API 删除的仓库默认进"归档"状态(目录移入存档区等待清理),定期清实测清单:

$ rhodecode-cleanup-repos --instance-name=community-1 --list-only -R /var/opt/rhodecode/repos

常用参数:--older-than=30d(只清归档超过 30 天的)、--dont-ask(脚本化免确认)、--include-groups(连同仓库组)。Gist 对应 rhodecode-cleanup-gists,参数一致。

六、日志与排障

6.1 日志文件清单与查看

文件内容看什么
/root/.rccontrol/community-1/community.logCommunity 应用日志(stdout_logfile,含访问行)HTTP 请求、慢请求、异常栈、API 调用
/root/.rccontrol/vcsserver-1/vcsserver.logVCSServer 日志clone/push 后端错误
/root/.rccontrol/supervisor/supervisord.logsupervisor 生命周期日志进程拉起/退出、BACKOFF/FATAL

应用日志格式(时间 <pid> 级别 [组件] 内容;每个 HTTP 请求两行——request_wrapper 摘要 + 访问行):

$ tail -8 /root/.rccontrol/community-1/community.log
2026-10-28 01:52:28.833 [10682] INFO  [rhodecode.model] RhodeCode 4.27.1 initializing db for postgresql://rhodecode:XXXXX@127.0.0.1:5432/rhodecode
2026-10-28 01:52:28.835 [10682] INFO  [rhodecode.config.environment] Enabled VCS backends: ['hg', 'git', 'svn']
2026-10-28 01:52:30.637 [10680] INFO  [rhodecode.config.middleware] Pyramid app `pyramid_app_with_cleanup` created and configured in 2.19s
2026-10-28 01:52:30.648 [10681] INFO  [rhodecode.config.middleware] Pyramid app `pyramid_app_with_cleanup` created and configured in 2.34s
2026-10-28 01:52:30.648 [10678] INFO  [rhodecode.config.middleware] Pyramid app `pyramid_app_with_cleanup` created and configured in 2.47s
2026-10-28 01:52:30.670 [10679] INFO  [rhodecode.config.middleware] Pyramid app `pyramid_app_with_cleanup` created and configured in 2.32s
2026-10-28 01:52:30.807 [10683] INFO  [rhodecode.config.middleware] Pyramid app `pyramid_app_with_cleanup` created and configured in 2.20s
2026-10-28 01:52:30.872 [10682] INFO  [rhodecode.config.middleware] Pyramid app `pyramid_app_with_cleanup` created and configured in 2.06s

supervisor 生命周期(restart 前后):

$ tail -5 /root/.rccontrol/supervisor/supervisord.log
2026-10-28 01:39:58,813 INFO success: community-1_script entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2026-10-28 01:52:24,774 INFO waiting for community-1_script to stop
2026-10-28 01:52:25,785 INFO stopped: community-1_script (exit status 0)
2026-10-28 01:52:25,788 INFO spawned: 'community-1_script' with pid 10667
2026-10-28 01:52:26,790 INFO success: community-1_script entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)

💡 两个实例的 redirect_stderr = true:gunicorn 的错误输出与应用日志同文件;交互式 tty 里也可用 supervisorctl tail -f community-1:community-1_script 实时跟踪(注意 3.3 的崩溃 bug 与绕过)。

6.2 API 调用日志核对

每次 API 调用在 community.log 里都有两行记录,可用来核对脚本是否真正到达服务端(status code / 耗时 / UA):

... Req[   1] <AuthUser('id:2[admin] ip:127.0.0.1 auth:False')> POST Request to /_admin/api time: 0.0977s [curl/7.81.0], RhodeCode 4.27.1
2026-10-28 01:52:43.560 <10682> INFO  [GNCRN] 127.0.0.1       rqt:0.099070 200 101    "POST:/_admin/api " usr:- "-" "curl/7.81.0"

6.3 交互式调试:rc-ishell

IPython 风格 shell,已加载应用环境(UserModel 等模型可直接用),适合 SQL/ORM 层面的核查;管道喂入实测:

$ echo 'from rhodecode.model.user import UserModel; print("ishell ok, version:", __import__("rhodecode").__version__)' | rc-ishell /root/.rccontrol/community-1/rhodecode.ini
In [1]: ('ishell ok, version:', '4.27.1')

6.4 rhodecode-config 的边界

rhodecode-config --update --filename=<ini> [段]键=值 可改配置(改完须重启实例生效);但 --show 在 4.27.1 实测并不可靠——对 ini 中存在的键返回空 {},对不存在的键直接抛 KeyError(如 KeyError: u'instance_title',CE 默认模板本就无此键)。因此读配置建议直接 grep ini 文件,写配置用 --update 或编辑器改完重启:

$ grep -n "search.location" /root/.rccontrol/community-1/rhodecode.ini
473:search.location = %(here)s/data/index

6.5 常见故障速查

现象定位处置
rccontrol status 显示 FATAL/BACKOFFsupervisord.log 看退出原因,community.log 看异常栈常见为数据库未就绪/端口占用,修复后 $SC start 组名:程序名
Web 502nginx 已通但 gunicorn 未监听看 ss -lntp | grep 10020,restart community-1
API 返回 Invalid API KEYtoken 过期/复制错Web 界面重新生成,同步更新 /root/.rhoderc
API 返回 No such method方法名不匹配 4.27 命名用报错附带的 Similar methods 或 get_method 兜底(见 4.5)
push 卡住/超时VCSServer 没起来$SC status 确认 vcsserver-1,restart 后重试
搜索无结果索引未建/键值变化重跑 rhodecode-index(5.5)
新建仓库在界面缺失磁盘与 DB 不同步rescan_repos(5.3)

七、FAQ

Q1:admin 的 API token 去哪里找? A:实例安装完成后写入 /root/.rhoderc(api_key 行);也可在 Web 界面右上角头像 → Profile → Auth Tokens 查看/生成新 token。本文所有 curl 示例中的 token 即取自该文件。

Q2:改了配置/权限为什么不生效? A:权限变更实时生效无需重启;rhodecode.ini 的配置变更需重启实例(rccontrol restart community-1 或 $SC restart community-1:community-1_script)。gunicorn 配置(worker 数等)改动同样走重启。

Q3:脚本能用什么语言调 API? A:任何能发 HTTP POST 的语言均可,协议是标准 JSON-RPC 2.0(字段 jsonrpc/id/method/args,鉴权 auth_token)。批量操作建议串行小步提交并检查每笔 error 字段;88 个方法全清单用 get_method(不带参数)拉取。

Q4:备份只需备 repos 目录吗? A:不够。数据库(用户/权限/PR/issue/审计)与 repos 目录(版本历史)各存一半,5.4 的 pg_dump + tar 双份都要做;第三方 Git 托管工具(如 gitea/gitlab)的裸仓库迁移进 RhodeCode 前,先在测试实例演练 create_repo → push --mirror → rescan_repos 流程。

Q5:如何安全地做整机重启? A:rccontrol self-stop → 重启服务器 → rccontrol self-init(supervisord 未托管时)或依赖 systemd 单元自启(安装篇的 unit 已配置 ExecStop=supervisorctl ... shutdown)。不要直接 kill gunicorn,supervisor 会按退避策略反复拉起造成双实例。

Q6:rhodecode-api 与 curl 直调该用哪个? A:临时查询/调试用 rhodecode-api(免拼 JSON、输出已格式化,读 /root/.rhoderc);脚本与自动化用 curl 直调(可控超时、可解析 error 结构、便于并发管理)。二者走同一端点同一鉴权,结果一致。

Q7:supervisorctl tail 一用就崩是坏了吗? A:不是。supervisor 4.1.0 的已知编码检查 bug(见 3.3 排障实录):非交互 stdout 下 sys.stdout.encoding 为 None 触发 AttributeError。交互终端直接可用;脚本环境加 export PYTHONIOENCODING=utf-8 或改为读日志文件。


本文全部命令于 2026-10-28 在 Ubuntu 22.04.5 LTS(RhodeCode Community 4.27.1 / VCSServer 4.27.1 / PostgreSQL 14)实测,回显逐行照抄;无法复现的环境相关输出已标注节选。