SCM-Manager 3.12.2 配置参数详解

逐层拆解 SCM-Manager 3.12.2 三级配置体系:/etc/default/scm-server 启动层堆参数、/etc/scm/config.yml 与 /opt 路径硬链接同源的服务层全参数、/api/v2/config 应用层默认值,附堆限制、端口、DEBUG 日志三组改参数实测闭环与 forceBaseUrl 307 全站重定向排障实录及生产配置模板。

SCM ManagerSCM Manager版本控制代码托管MercurialUbuntu 22.042026/10/28

SCM-Manager 3.12.2 配置参数详解

本文基于 Ubuntu 22.04.5 LTS + SCM-Manager 3.12.2 实测环境,逐层拆解配置体系:启动层 /etc/default/scm-server、服务层 /etc/scm/config.yml(与 /opt/scm-server/conf/config.yml 为同一文件)、应用层 Web/REST 配置,并给出三组"改参数→重启→验证"实测闭环与一个 forceBaseUrl 引发的 307 全站重定向排障实录。安装背景见《SCM-Manager 3.12.2 Ubuntu 22.04 安装指南》,选型背景见《SCM-Manager 介绍与选型指南》。

一、配置体系总览

SCM-Manager 3.12.2 的配置分三层,权属与生效方式实测如下:

层级路径载体生效方式
启动层(JVM/进程)/etc/default/scm-servershell 环境变量重启服务
服务层(HTTP/日志/工作线程)/etc/scm/config.ymlYAML重启服务
应用层(业务行为)Web 管理界面 / REST /api/v2/config 等SQLite(/var/lib/scm/scm.db)保存即时生效

两点实测结论先行:

  1. /etc/scm/config.yml 与 /opt/scm-server/conf/config.yml 是同一个文件:实测两路径 stat -c "%i" 均为 inode 3672632,编辑任意一份内容同步变化(我们 sed 修改 /opt 路径后,/etc 路径 grep 立即看到相同值,重启后监听端口随之改变)。该文件属主 root:scm、权限 640,非 root 编辑需相应权限;
  2. 服务层文件改错不会导致服务崩溃起不来——YAML 解析失败时启动日志会打印解析异常并退出,journalctl -u scm-server 可定位(实测环境未触发,此为官方文档 Troubleshooting 指引路径)。

二、启动层:/etc/default/scm-server

deb 包安装的默认内容(实测节选,许可头略):

# force jvm path
# JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64"

# increase memory
# EXTRA_JVM_ARGUMENTS="$EXTRA_JVM_ARGUMENTS -Xms1g -Xmx1g"

# pass extra jvm arguments
EXTRA_JVM_ARGUMENTS="$EXTRA_JVM_ARGUMENTS"

参数说明:

  • JAVA_HOME:默认注释。3.12.2 需要 Java 17,deb 依赖已装 OpenJDK 17(实测 java -version 为 17.0.20.1);系统存在多版本 JDK 时在此强制指向 17 的安装目录;
  • EXTRA_JVM_ARGUMENTS:追加给 JVM 的参数,默认堆未显式限制(JVM 自行按物理内存 1/4 取默认上限)。

2.1 实测闭环:限制堆为 256MB

生产建议显式控堆(512MB 内可稳定承载中小团队,与选型篇资源口径一致)。实测过程与回显:

# cp /etc/default/scm-server /etc/default/scm-server.orig
# echo "EXTRA_JVM_ARGUMENTS=\"-Xms128m -Xmx256m\"" >> /etc/default/scm-server
# tail -2 /etc/default/scm-server
EXTRA_JVM_ARGUMENTS="$EXTRA_JVM_ARGUMENTS"
EXTRA_JVM_ARGUMENTS="-Xms128m -Xmx256m"
# systemctl restart scm-server && sleep 14
# ps aux | grep -o "\-Xms128m -Xmx256m" | head -1
-Xms128m -Xmx256m
# systemctl status scm-server --no-pager | grep -E "Memory|Active"
     Active: active (running) since Wed 2026-10-28 02:04:56 UTC; 14s ago
     Memory: 340.2M

结论:-Xms128m -Xmx256m 经 scm-server 启动脚本透传至 Java 进程(ps 实证),进程 RSS 340.2M(堆 256M + 元空间与堆外)。未控堆时实测 RSS 为 284M~420M 波动(默认堆上限随宿主内存而定)。改堆必须重启服务,仅重载无效。

三、服务层:/etc/scm/config.yml 逐项

默认文件全文结构(3.12.2 实测,注释保留):

addressBinding: 0.0.0.0
port: 8080
contextPath: /scm

forwardHeadersEnabled: false
httpHeaderSize: 16384

https:
  keyStorePath: ""
  keyStorePassword: secret
  keyStoreType: PKCS12
  sslPort: 8443
  redirectHttpToHttps: false

tempDir: /var/cache/scm/work

log:
  logDir: /var/log/scm
  rootLevel: WARN
  enableFileAppender: true
  enableConsoleAppender: false
  logger:
    sonia.scm: INFO
    com.cloudogu.scm: INFO

webapp:
  workDir:
  homeDir: /var/lib/scm
  cache:
    dataFile:
      enabled: true
    store:
      enabled: true
  endlessJwt: false
  asyncThreads: 4
  maxAsyncAbortSeconds: 60
  centralWorkQueue:
    workers: 4
  workingCopyPoolStrategy: sonia.scm.repository.work.SimpleCachingWorkingCopyPool
  workingCopyPoolSize: 5

3.1 HTTP 服务段

参数默认值说明
addressBinding0.0.0.0监听地址,全部网卡;内网限定场景可绑具体网卡 IP
port8080HTTP 端口
contextPath/scmWeb 上下文路径,Web 入口与 API 前缀均受其影响
forwardHeadersEnabledfalse是否信任反向代理的 X-Forwarded-For/Proto/Host 头,置于 Nginx 之后时改为 true
httpHeaderSize16384HTTP 头最大字节数,注释说明为 Mercurial 场景调大

3.2 实测闭环:修改监听端口

# cp /etc/scm/config.yml /etc/scm/config.yml.orig
# sed -i "s/^port: 8080/port: 8090/" /etc/scm/config.yml && grep -n "^port:" /etc/scm/config.yml
20:port: 8090
# systemctl restart scm-server && sleep 14
# curl -s -o /dev/null -w "port8090:%{http_code}\n" http://localhost:8090/scm/
port8090:200
# curl -s -o /dev/null -w "port8080:%{http_code}\n" --max-time 3 http://localhost:8080/scm/
port8080:000

端口修改重启后生效(8090 返回 200,8080 停止响应)。验证完毕恢复为 8080(实测恢复后 200)。

3.3 HTTPS 段

参数默认值说明
https.keyStorePath""PKCS12 密钥库路径;留空则整段 SSL 配置不生效(注释原文:ssl is only evaluated if key store path is set)
https.keyStorePasswordsecret密钥库口令
https.keyStoreTypePKCS12密钥库类型
https.sslPort8443HTTPS 端口
https.redirectHttpToHttpsfalse是否将 HTTP 请求重定向到 HTTPS

启用内置 HTTPS 的最小操作:用 keytool -genkeypair 生成 PKCS12 库,填 keyStorePath 与口令后重启。生产更常见做法是保持 HTTP + 前置 Nginx 做 TLS 终结,此时记得把 forwardHeadersEnabled 改为 true。

3.4 日志段

参数默认值说明
log.logDir/var/log/scm日志目录(deb 包默认,主日志文件 scm-manager.log)
log.rootLevelWARN全局日志级别
log.enableFileAppendertrue写文件
log.enableConsoleAppenderfalse写标准输出(journalctl 场景可开)
log.logger.sonia.scmINFO主程序日志级别
log.logger.com.cloudogu.scmINFOCloudogu 插件日志级别

3.5 实测闭环:DEBUG 日志

# wc -l < /var/log/scm/scm-manager.log
373
# sed -i "s/^  rootLevel: WARN/  rootLevel: DEBUG/" /etc/scm/config.yml
# sed -i "s/^    sonia.scm: INFO/    sonia.scm: DEBUG/" /etc/scm/config.yml
# systemctl restart scm-server && sleep 14
# tail -3 /var/log/scm/scm-manager.log | cut -c1-90
2026-10-28 02:06:03.621 [qtp935044096-21] [          ] DEBUG org.hibernate.validator.internal.engine.ValidatorFa
2026-10-28 02:06:03.621 [qtp935044096-21] [          ] DEBUG org.jboss.resteasy.plugins.validation.i18n - RESTEASY
2026-10-28 02:06:03.637 [qtp935044096-21] [DWVZJ1vvq1] DEBUG sonia.scm.template.MustacheTemplate - render mustach

rootLevel: DEBUG 生效后,第三方框架(hibernate-validator、RESTEasy)DEBUG 行大量出现,日志体积显著增长,仅建议临时排障使用,排障后恢复 WARN/INFO 并重启。

3.6 webapp 运行段

参数默认值说明
webapp.homeDir/var/lib/scm数据主目录(仓库、元数据、插件)
webapp.workDir空(用 Java 默认临时目录)内部进程工作目录
webapp.endlessJwtfalse会话 JWT 永不过期;注释明确警告有安全风险,保持 false
webapp.asyncThreads4异步线程数
webapp.maxAsyncAbortSeconds60异步任务中止等待上限
webapp.centralWorkQueue.workers4中央工作队列并发 worker 数
webapp.workingCopyPoolStrategySimpleCachingWorkingCopyPool工作副本池策略,另一可选值 NoneCachingWorkingCopyPool(不缓存)
webapp.workingCopyPoolSize5缓存的工作副本数量

tempDir: /var/cache/scm/work 为 Web 应用临时目录(卸载时的 not empty 警告即来自这里)。cache.dataFile/store.enabled 为内置缓存开关,保持默认。

四、应用层:Web 管理与 REST 配置

4.1 全局配置项与实测默认值

应用层配置经 Web 界面(管理 → Settings)或 REST GET/PUT /api/v2/config 管理。3.12.2 全新实例默认值实测(admin 会话):

配置项实测默认值说明
baseUrlnull对外访问基准地址,建议部署后必配
forceBaseUrlfalse开启后强制所有请求重定向到 baseUrl
realmDescription"SONIA :: SCM Manager"登录页描述文案
anonymousAccessEnabledfalse匿名访问总开关
anonymousMode(随开关)匿名模式细分
loginAttemptLimit-1登录失败次数上限(-1 不限制),生产建议设 10~30
loginAttemptLimitTimeout300超限锁定秒数
jwtExpirationInH(数值型)会话令牌有效期(小时)
enabledXsrfProtection(布尔)XSRF 防护开关
enabledApiKeys(布尔)API Key 功能开关
mailDomainName"scm-manager.local"默认邮箱域补全
proxyServer/proxyPort/proxyUser/proxyPassword/enableProxy/proxyExcludes关闭出网代理(插件中心拉取走此配置)
namespaceStrategy空仓库命名空间策略
emergencyContacts空紧急联系人(告警用)

4.2 实测闭环:PUT 修改 baseUrl(含 307 排障实录)

# curl -s -b /tmp/cookies.txt -X PUT http://localhost:8080/scm/api/v2/config \
>   -H "Content-Type: application/vnd.scmm-config+json;v=2" \
>   -d '{"baseUrl":"http://192.168.1.50:8080/scm","forceBaseUrl":true,"realmDescription":"SONIA :: SCM Manager","anonymousAccessEnabled":false,"loginAttemptLimit":-1,"loginAttemptLimitTimeout":300,"mailDomainName":"scm-manager.local", ... }' \
>   -o /dev/null -w "PUT:%{http_code}\n"
PUT:204
# curl -s -b /tmp/cookies.txt http://localhost:8080/scm/api/v2/config | python3 -m json.tool | grep -E "baseUrl"
307

排障实录:把 forceBaseUrl 与一个不可达的 baseUrl(192.168.1.50 为示例假地址)同时保存后,本机全部请求立刻开始返回 307 重定向——服务把所有流量强制跳往 baseUrl,包括正在使用的管理会话本身。Web 界面同样会跳向错误地址,且配置存在 SQLite 内、不走 config.yml,改文件无效。实测修复路径(curl --connect-to 将假地址映射回本机后重新登录并 PUT 恢复):

# curl -s -L -c /tmp/ck2 -X POST --connect-to 192.168.1.50:8080:127.0.0.1:8080 \
>   http://192.168.1.50:8080/scm/api/v2/auth/access_token -H "Content-Type: application/json" \
>   -d '{"cookie":true,"grant_type":"password","username":"scmadmin","password":"q1w2e3r4"}' -o /dev/null -w "login:%{http_code}\n"
login:204
# curl -s -b /tmp/ck2 --connect-to 192.168.1.50:8080:127.0.0.1:8080 -X PUT \
>   http://192.168.1.50:8080/scm/api/v2/config -H "Content-Type: application/vnd.scmm-config+json;v=2" \
>   -d '{"baseUrl":null,"forceBaseUrl":false, ...}' -o /dev/null -w "PUT_restore:%{http_code}\n"
PUT_restore:204
# curl -s -b /tmp/ck2 --connect-to 192.168.1.50:8080:127.0.0.1:8080 -L http://192.168.1.50:8080/scm/api/v2/config | grep -o '"baseUrl":[^,]*'
"baseUrl":null

经验结论:baseUrl 填真实对外地址再开 forceBaseUrl;两者不同时改;若已中招,--connect-to(或直接给服务器加临时 IP)是唯一无需动数据库的恢复手段。PUT 时服务端接受不带 If-Match 乐观锁头的请求(实测 204),但标准用法建议先 GET /api/v2/config 取 ETag 头一并提交,避免并发覆盖。

4.3 仓库级与其他配置入口

  • 仓库创建与配置:POST/PUT /api/v2/repositories/,类型 git/hg/svn;
  • 用户/组/权限:/api/v2/users、/api/v2/groups、/api/v2/permissions(命令化操作见运维篇);
  • 插件:/api/v2/plugins/available 与 /installed;
  • 认证配置(LDAP 等):/api/v2/config/authentications(装对应插件后出现)。

五、生产配置模板

中小团队(≤50 人)单机推荐基线,全部经本文实测项组合:

# /etc/default/scm-server —— 启动层
JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
EXTRA_JVM_ARGUMENTS="-Xms256m -Xmx512m"
# /etc/scm/config.yml —— 服务层(与 /opt/scm-server/conf/config.yml 同一文件)
addressBinding: 0.0.0.0
port: 8080
contextPath: /scm
forwardHeadersEnabled: true        # 前置 Nginx 时开启
httpHeaderSize: 16384
https:
  keyStorePath: ""                 # TLS 交给 Nginx,内置 SSL 不启用
  keyStorePassword: secret
  keyStoreType: PKCS12
  sslPort: 8443
  redirectHttpToHttps: false
tempDir: /var/cache/scm/work
log:
  logDir: /var/log/scm
  rootLevel: WARN
  enableFileAppender: true
  enableConsoleAppender: false
  logger:
    sonia.scm: INFO
    com.cloudogu.scm: INFO
webapp:
  homeDir: /var/lib/scm
  endlessJwt: false                # 安全红线,保持 false
  asyncThreads: 4
  maxAsyncAbortSeconds: 60
  centralWorkQueue:
    workers: 4
  workingCopyPoolStrategy: sonia.scm.repository.work.SimpleCachingWorkingCopyPool
  workingCopyPoolSize: 5

应用层(Web Settings 或 REST):baseUrl 设为对外真实地址(如 https://scm.example.com/scm)并确认可达后再开 forceBaseUrl;loginAttemptLimit 设 10、loginAttemptLimitTimeout 保持 300;anonymousAccessEnabled 保持 false。

六、配置排障清单

  1. 改了配置不生效:启动层与服务层改动均需 systemctl restart scm-server;确认编辑的是硬链接同一份 /etc/scm/config.yml(改 /opt/scm-server/conf/ 下的等效);
  2. 服务起不来:journalctl -u scm-server --no-pager + /var/log/scm/scm-manager.log 双路取证;YAML 缩进错误(config.yml 段下必须两空格层级)与 /etc/default/scm-server 引号不配对是高频原因;
  3. 全站 307:forceBaseUrl + 错误 baseUrl 所致,见 4.2 排障实录;
  4. JWT 频繁过期:按需调 jwtExpirationInH,严禁开 endlessJwt;
  5. 端口被占:port 改动后与既有进程冲突时启动失败,ss -tlnp | grep <port> 先行确认(命令+预期结果:输出含 LISTEN 行即为被占)。