TiMa

Gitlab Docker部署gitaly启动失败问题

在NAS上部署docker版gitlab,发现其他都正常,创建群组也正常,但是创建项目就会报500错误,

Request ID: 01JXKP6NTCNM201KEGMSDHFJ2J

查运行状态,gitaly未运行,有大量的gitaly错误日志,错误信息大致如下:

{"error":"open /var/opt/gitlab/gitaly/gitaly.pid: permission denied","level":"fatal","msg":"find process","pid":3499,"time":"2025-06-13T14:56:03.048Z","wrapper":3499}
unclean Gitaly shutdown: creating Git command factory: setting up Git execution environment: constructing Git environment: Checking bundled Git binary "gitaly-git-v2.49": permission denied
{“level”:“warning”,“msg”:“The current configurations will cause Gitaly to fail to start up in future versions. Please run ‘gitaly configuration validate \u003c /var/opt/gitlab/gitaly/config.toml’ and fix the errors that are printed.”,“pid”:46135,“time”:“2025-06-13T14:59:34.981Z”}
FAIL: 14:connections to all backends failing; last error: UNKNOWN: unix:/var/opt/gitlab/gitaly/gitaly.socket: No such file or directory

换了好几个版本都是如此,经过大量查询和AI解释,都只解释了一半,主要与 GitLab 容器内 gitaly-git 二进制文件的权限或配置异常有关,也没有给准确的建议。这个问题的原因在于/var是一个受noexec保护的路径,禁止运行gitaly服务程序,而gitaly的运行目录正好位于:/var/opt/gitlab/gitaly/

即便做了目录持久化挂载,给了读写权限,给了git用户/组权限,也会受目录保护影响,解决方案有两个:

方法一:

如果可以登录宿主机,在/etc/fstab 取消/var保护

步骤(参考):

  1. 检查 /var 目录的挂载选项:
    • 在终端中运行 mount | grep /var 命令,查看 /var 目录的挂载选项。
    • 检查输出中是否包含 noexec 选项。
  2. 修改 /etc/fstab 文件:
    • 使用文本编辑器(例如 nano 或 vim)以 root 权限打开 /etc/fstab 文件:sudo nano /etc/fstab
    • 找到与 /var 目录相关的行。该行通常包含设备、挂载点 /var、文件系统类型以及挂载选项等信息。
    • 在挂载选项列表中,移除 noexec 选项。如果存在其他选项,请确保保留它们。
    • 示例:
      如果原始行是:/dev/sda1 /var ext4 defaults,noexec,nosuid 0 2 修改后应为:/dev/sda1 /var ext4 defaults,nosuid 0 2
    • 保存并关闭文件.
  3. 重新加载 systemd 配置:
    • 如果你修改了 /etc/fstab,为了让系统识别新的配置,需要重新加载 systemd 配置:sudo systemctl daemon-reload
  4. 重新挂载 /var 目录:
    • 使用 mount -o remount 命令重新挂载 /var 目录,以使更改生效:sudo mount -o remount /var
    • 注意: 在执行此操作之前,最好停止 GitLab 服务,以避免可能的问题。
  5. 验证更改:
    • 再次运行 mount | grep /var 命令,确认 noexec 选项已经被移除。 

方法二:

如果无法进入Docker宿主机,比如我在NAS上的docker服务运行,无法进入NAS的shell,那就只能修改gitaly运行目录,用shell命令行控制台进到容器内

1、复制或创建gitaly目录:

mkdir /opt/gitlab/gitaly
chown -R 777 git:git /opt/gitlab/gitaly

或:
scp -r /var/opt/gitlab/gitaly /opt/gitlab/
chown -R 777 git:git /opt/gitlab/gitaly

2、修改/var/opt/gitlab/gitaly/config.toml配置文件

runtime_dir = "/var/opt/gitlab/gitaly/run"
socket_path = "/var/opt/gitlab/gitaly/gitaly.socket"

修改为:

runtime_dir = "/opt/gitlab/gitaly/run"
socket_path = "/opt/gitlab/gitaly/gitaly.socket"

3、修改/etc/gitlab/gitlab.rb中gitaly配置runtime_dir和socket_path参数,大约位于2658行左右,原配置是全注释的

# gitaly['configuration'] = {
#   socket_path: '/var/opt/gitlab/gitaly/gitaly.socket',
#   runtime_dir: '/var/opt/gitlab/gitaly/run',
#   listen_addr: 'localhost:8075',
#   prometheus_listen_addr: 'localhost:9236',
#   tls_listen_addr: 'localhost:9075',
#   tls: {
#     certificate_path: '/var/opt/gitlab/gitaly/certificate.pem',
#     key_path: '/var/opt/gitlab/gitaly/key.pem',
#   },
#   graceful_restart_timeout: '1m', # Grace time for a gitaly process to finish ongoing requests
#   logging: {
#     dir: "/var/log/gitlab/gitaly",
#     level: 'warn',
#     format: 'json',
#     sentry_dsn: 'https://<key>:<secret>@sentry.io/<project>',
#     sentry_environment: 'production',
#   },
#   prometheus: {
#     grpc_latency_buckets: [0.001, 0.005, 0.025, 0.1, 0.5, 1.0, 10.0, 30.0, 60.0, 300.0, 1500.0],
#   },
#   auth: {
#     token: '<secret>',
#     transitioning: false, # When true, auth is logged to Prometheus but NOT enforced
#   },
#   git: {
#     catfile_cache_size: 100, # Number of 'git cat-file' processes kept around for re-use
#     bin_path: '/opt/gitlab/embedded/bin/git', # A custom path for the 'git' executable
#     use_bundled_binaries: true, # Whether to use bundled Git.
#     signing_key: '/var/opt/gitlab/gitaly/signing_key.gpg',
#     ## Gitaly knows to set up the required default configuration for spawned Git
#     ## commands automatically. It should thus not be required to configure anything
#     ## here, except in very special situations where you must e.g. tweak specific
#     ## performance-related settings or enable debugging facilities. It is not safe in
#     ## general to set Git configuration that may change Git output in ways that are
#     ## unexpected by Gitaly.
#     config: [
#       { key: 'pack.threads', value: '4' },
#       { key: 'http.http://example.com.proxy', value: 'http://example.proxy.com' },
#     ],
#   },
#   gitlab: {
#     url: 'http://localhost:9999',
#     relative_url_root: '/gitlab-ee',
#   },
#   hooks: {
#     custom_hooks_dir: '/var/opt/gitlab/gitaly/custom_hooks',
#   },
#   daily_maintenance: {
#     disabled: false,
#     start_hour: 22,
#     start_minute: 30,
#     duration: '30m',
#     storages: ['default'],
#   },
#   cgroups: {
#     mountpoint: '/sys/fs/cgroup',
#     hierarchy_root: 'gitaly',
#     memory_bytes: 1048576,
#     cpu_shares: 512,
#     cpu_quota_us: 400000,
#     repositories: {
#       count: 1000,
#       memory_bytes: 12884901888,
#       cpu_shares: 128,
#       cpu_quota_us: 200000
#       max_cgroups_per_repo: 2
#     },
#   },
#   concurrency: [
#     {
#       rpc: '/gitaly.SmartHTTPService/PostReceivePack',
#       max_per_repo: 20,
#     },
#     {
#       rpc: '/gitaly.SSHService/SSHUploadPack',
#       max_per_repo: 5,
#     },
#   ],
#   rate_limiting: [
#     {
#       rpc: '/gitaly.SmartHTTPService/PostReceivePack',
#       interval: '1m',
#       burst: 10,
#     },
#     {
#       rpc: '/gitaly.SSHService/SSHUploadPack',
#       interval: '1m',
#       burst: 5,
#     },
#   ],
#   pack_objects_cache: {
#     enabled: true,
#     dir: '/var/opt/gitlab/git-data/repositories/+gitaly/PackObjectsCache',
#     max_age: '5m',
#   },
#   storage: [
#     {
#       name: 'gitaly-1',
#       path: '/var/opt/gitlab/git-data/repositories',
#     },    
#   ],
# }

修改为:去掉gitaly[‘configuration’]、socket_path、runtime_dir以及(大约2759行)结束大括号}的注释

gitaly['configuration'] = {
#   socket_path: '/opt/gitlab/gitaly/gitaly.socket',
#   runtime_dir: '/opt/gitlab/gitaly/run',
#   listen_addr: 'localhost:8075',
#   prometheus_listen_addr: 'localhost:9236',
#   tls_listen_addr: 'localhost:9075',
#   tls: {
#     certificate_path: '/var/opt/gitlab/gitaly/certificate.pem',
#     key_path: '/var/opt/gitlab/gitaly/key.pem',
#   },
#   graceful_restart_timeout: '1m', # Grace time for a gitaly process to finish ongoing requests
#   logging: {
#     dir: "/var/log/gitlab/gitaly",
#     level: 'warn',
#     format: 'json',
#     sentry_dsn: 'https://<key>:<secret>@sentry.io/<project>',
#     sentry_environment: 'production',
#   },
#   prometheus: {
#     grpc_latency_buckets: [0.001, 0.005, 0.025, 0.1, 0.5, 1.0, 10.0, 30.0, 60.0, 300.0, 1500.0],
#   },
#   auth: {
#     token: '<secret>',
#     transitioning: false, # When true, auth is logged to Prometheus but NOT enforced
#   },
#   git: {
#     catfile_cache_size: 100, # Number of 'git cat-file' processes kept around for re-use
#     bin_path: '/opt/gitlab/embedded/bin/git', # A custom path for the 'git' executable
#     use_bundled_binaries: true, # Whether to use bundled Git.
#     signing_key: '/var/opt/gitlab/gitaly/signing_key.gpg',
#     ## Gitaly knows to set up the required default configuration for spawned Git
#     ## commands automatically. It should thus not be required to configure anything
#     ## here, except in very special situations where you must e.g. tweak specific
#     ## performance-related settings or enable debugging facilities. It is not safe in
#     ## general to set Git configuration that may change Git output in ways that are
#     ## unexpected by Gitaly.
#     config: [
#       { key: 'pack.threads', value: '4' },
#       { key: 'http.http://example.com.proxy', value: 'http://example.proxy.com' },
#     ],
#   },
#   gitlab: {
#     url: 'http://localhost:9999',
#     relative_url_root: '/gitlab-ee',
#   },
#   hooks: {
#     custom_hooks_dir: '/var/opt/gitlab/gitaly/custom_hooks',
#   },
#   daily_maintenance: {
#     disabled: false,
#     start_hour: 22,
#     start_minute: 30,
#     duration: '30m',
#     storages: ['default'],
#   },
#   cgroups: {
#     mountpoint: '/sys/fs/cgroup',
#     hierarchy_root: 'gitaly',
#     memory_bytes: 1048576,
#     cpu_shares: 512,
#     cpu_quota_us: 400000,
#     repositories: {
#       count: 1000,
#       memory_bytes: 12884901888,
#       cpu_shares: 128,
#       cpu_quota_us: 200000
#       max_cgroups_per_repo: 2
#     },
#   },
#   concurrency: [
#     {
#       rpc: '/gitaly.SmartHTTPService/PostReceivePack',
#       max_per_repo: 20,
#     },
#     {
#       rpc: '/gitaly.SSHService/SSHUploadPack',
#       max_per_repo: 5,
#     },
#   ],
#   rate_limiting: [
#     {
#       rpc: '/gitaly.SmartHTTPService/PostReceivePack',
#       interval: '1m',
#       burst: 10,
#     },
#     {
#       rpc: '/gitaly.SSHService/SSHUploadPack',
#       interval: '1m',
#       burst: 5,
#     },
#   ],
#   pack_objects_cache: {
#     enabled: true,
#     dir: '/var/opt/gitlab/git-data/repositories/+gitaly/PackObjectsCache',
#     max_age: '5m',
#   },
#   storage: [
#     {
#       name: 'gitaly-1',
#       path: '/var/opt/gitlab/git-data/repositories',
#     },    
#   ],
}

执行:gitlab-ctl reconfigure 重载配置

重启gitlab:gitlab-ctl restart

方法二处理起来比较容易,亲测有效

如果是NAS,不支持docker exec命令行,那建议借助Portainer容器管理器,先运行docker版的Portainer,用Portainer来部署gitlab管理docker及docker-compose比较方便。

参考来源:https://gitlab.com/gitlab-org/gitlab/-/issues/?sort=created_date&state=opened&search=noexec&first_page_size=20

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注