news 2026/10/13 8:12:27

CentOS 7.9实战:GitLab CE部署与项目迁移完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CentOS 7.9实战:GitLab CE部署与项目迁移完整指南

1. 为什么我在 CentOS 7.9 上部署 GitLab CE

这段时间在内网环境里做了一次完整的代码托管平台迁移:从旧实例把一批项目搬到一台新的 CentOS 7.9 服务器,顺便把 GitLab CE 的版本统一升级部署,期间还折腾了公司网络里必须走 HTTP 代理才能出网的各种配置。整个过程踩了不少坑,但最终稳定跑起来了。

先说说为什么还是选 CentOS 7.9。虽然它已经过了官方维护期,但存量生产环境的惯性确实很大,很多公司内部跑着的还是 7.x 系列,业务平稳、运维习惯成熟,短期内不可能全部换掉。GitLab CE 官方对 CentOS 7 的支持也一直覆盖到最后,所以新机器继续用 7.9,至少部署和维护成本最低,迁移风险也相对可控。

这套方案解决的核心问题有三个:第一,在内网离线或半隔离网络环境里完整部署 GitLab CE;第二,把旧 GitLab 上的项目(仓库、分支、标签、合并请求、Issue、成员关系)尽可能无损地搬到新实例;第三,搞定公司代理环境下面临的一系列特殊配置。适合正在做同类迁移的运维同行、刚接手公司代码平台的新人,以及准备从其他平台迁到 GitLab 的团队参考。

我的建议是先把下面这些章节当一份操作手册来看,每一步都写了为什么这么做、报错了怎么处理。遇到和你环境不一样的地方,先把原理搞清楚,再套自己的参数,别无脑照抄命令。

2. 部署前的系统准备

2.1 检查硬件与系统信息

GitLab 是个吃资源不眨眼的家伙。官方推荐的最低配置是 4GB 内存、2 核 CPU,但那是“能跑”的最低标准。如果你打算同时承担几十个项目和几十个开发者的日常操作,4GB 会非常勉强。我这次给的是 8GB 内存、4 核 CPU,另外单独划了 20GB 的备份和日志盘,总算舒服一些。

动手之前先确认三件事:

  • 系统版本:cat /etc/redhat-release,确认是 CentOS Linux release 7.9.2009。
  • 内存和磁盘:free -h、df -h,至少保证根分区有 30GB 左右剩余空间,并且/var/opt/gitlab所在的挂载点空间足够。
  • 架构:uname -m,GitLab 官方 rpm 包只提供 x86_64 和 aarch64,别拿到包才发现架构不对。

2.2 基础软件包与 Yum 源

CentOS 7 安装源里默认有很多软件,但 GitLab 安装过程中可能依赖其他组件。先把基础包补上:

yum update -y yum install -y curl policycoreutils openssh-server openssh-clients postfix perl

这里的openssh-server是 GitLab 通过 SSH 协议提供 Git 操作必须的;policycoreutils和postfix是 GitLab 官方安装文档里明确列出来的依赖。postfix 用来发邮件通知,如果你已经有内网邮件服务器,也可以后面单独改 SMTP,这里先装上不碍事。

如果你所在网络不能直接访问 yum 源,那就要先配置代理。这里有个小细节:在yum.conf里加代理是全局生效的,建议配置文件里写代理,而不是每次手动 export 环境变量,否则后面安装 GitLab rpm 包时还容易踩“依赖包拉不下来”的坑。配置方法:

# /etc/yum.conf proxy=http://proxy.internal.example.com:3128 proxy_username= proxy_password=

配置完执行yum clean all && yum makecache验证一下,能跑通再继续。如果公司网络只允许特定域名直连,比如内网软件源域名不需要代理,可以在 yum 源配置文件里把不需要代理的域名加进exclude或单独指定 baseurl,这里不展开,原理都是告诉系统哪些流量该走代理、哪些不该走。

3. 安装 GitLab CE 实操记录

3.1 接入软件源与安装

GitLab 提供了独立软件源,官方安装脚本会把源写到/etc/yum.repos.d/下。脚本本身需要从 GitLab 官网拉取,如果你的服务器不能直连,就得先把脚本下载到本机,或者手动创建 yum 源文件指向内网镜像。

我是手动配置的源,避免官方脚本因为网络问题半路失败:

cat > /etc/yum.repos.d/gitlab_gitlab-ce.repo <<'EOF' [gitlab_gitlab-ce] name=gitlab_gitlab-ce baseurl=https://packages.gitlab.com/gitlab/gitlab-ce/el/7/$basearch repo_gpgcheck=1 enabled=1 gpgcheck=1 gpgkey=https://packages.gitlab.com/gitlab/gitlab-ce/gpgkey sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt EOF

如果你的服务器无法访问packages.gitlab.com,也可以把 rpm 包下载到内网,然后通过yum localinstall安装。我遇到过只允许访问特定内网域名的情况,做法是先在一台有外网权限的机器上下载 gitlab-ce 的 rpm 包和所有依赖,再拷贝进内网。依赖比较多的时候,用createrepo把本地目录做成临时 yum 源,最后只需要yum install -y gitlab-ce-版本号.el7.x86_64.rpm一条命令。

安装时指定EXTERNAL_URL,这决定了用户访问 GitLab 的地址:

EXTERNAL_URL="http://gitlab.internal.example.com" yum install -y gitlab-ce

如果你的环境打算走 HTTPS,这里就写成https://gitlab.internal.example.com,但后面还要配置证书和 NGINX 相关参数。初次部署我用 HTTP,把证书问题放后面统一处理,省得一开始就被 HTTPS 握手挡在门外。安装过程会自动跑一遍gitlab-ctl reconfigure,正常情况下会看到一堆 “Recipe: omnibus-gitlab::gitlab-rails” 之类的输出,最后显示gitlab Reconfigured!。

3.2 初始化配置与首次登录

安装完成后,root 用户的初始密码被写在临时文件/etc/gitlab/initial_root_password里。这个文件默认会在 24 小时后被删除,所以要趁早改密码:

grep 'Password:' /etc/gitlab/initial_root_password

然后打开浏览器访问http://gitlab.internal.example.com,用 root 和这个临时密码登录,立刻修改密码。如果用命令行改,也可以执行:

gitlab-rails console u = User.find_by(username: 'root') u.password = '新的复杂密码' u.password_confirmation = '新的复杂密码' u.save!

我当时发现登录后很多页面提示 “You have to confirm your account before continuing”,后来排查发现是环境里邮件服务没配好,导致确认邮件发不出去。解决办法是在管理后台把 root 的确认状态改成已验证,或者在gitlab.rb里配置好 SMTP 服务。

4. 把旧实例的项目搬到新实例

4.1 迁移前先列清楚这些清单

迁移项目最怕的是什么?不是仓库丢,而是“仓库过来了,配置全没了”。所以动手前一定要列清楚:

  • 项目仓库本身:分支、标签、提交历史。
  • 项目元数据:Merge Request、Issue、Milestone、Wiki、Snippets。
  • 访问控制:成员及权限、Deploy Keys、Protected Branches。
  • 集成配置:Webhooks、CI/CD 变量、Container Registry、Runner 绑定关系。
  • 全局配置:License、SSH 公钥、邮箱配置、自定义域名。

迁移的方式主要看你想搬多少:全部搬、按组搬、还是按项目搬。我这次因为旧实例快满了,需要整体搬迁,所以先做了一次完整的 GitLab 备份恢复,再针对后续新增的少数项目单独做了项目导出导入。

4.2 全量备份恢复的迁移方式

全量迁移适合新旧实例版本一致,或者至少主版本号相近的情况。GitLab 官方对跨大版本迁移的态度是:先升级源实例到目标相同或相近版本,再做备份恢复,不要直接跨好几个大版本恢复备份。

在旧实例上执行:

gitlab-backup create

备份完成后,备份文件在/var/opt/gitlab/backups/下,文件名形如1720000000_2025_07_01_16.11.8_gitlab_backup.tar。除了这个备份文件,还有两个配置文件必须一起带走:

  • /etc/gitlab/gitlab.rb
  • /etc/gitlab/gitlab-secrets.json

gitlab-secrets.json这个文件特别容易漏。它保存了 GitLab 的加密密钥,包括数据库加密密钥、OTP 密钥等。如果恢复时源、目标两边该文件不一致,会出现用户登录后二次验证失效、Runner token 对不上等问题。我见过有人把 secrets 文件丢了,结果整个实例的 2FA 全部重置,属于灾难级事故。

在新实例上恢复的流程是:

  1. 先确保新实例安装的 GitLab 版本和备份数据版本一致,必要时先升级到一致版本。
  2. 把gitlab.rb和gitlab-secrets.json拷贝到新实例对应目录。
  3. 执行gitlab-ctl reconfigure。
  4. 把备份 tar 文件放到新实例/var/opt/gitlab/backups/目录下,并确认文件属主是git:git。
  5. 停掉与数据库写入相关的服务,防止恢复过程中数据写入冲突:
gitlab-ctl stop puma gitlab-ctl stop sidekiq gitlab-ctl stop nginx
  1. 执行恢复:
gitlab-backup restore BACKUP=1720000000_2025_07_01_16.11.8

恢复过程会提示确认,输入yes继续。恢复完成后重启服务:

gitlab-ctl reconfigure gitlab-ctl restart

4.3 用项目导入导出做定向迁移

如果只是搬几个项目,不需要全量备份恢复,用项目导出导入更灵活。你可以在旧实例的某个项目里进入“设置 -> 通用 -> 导出项目”,GitLab 会生成一个包含项目仓库和元数据的 tar.gz 文件,下载后在新实例里通过“新建项目 -> 导入项目”上传即可。

项目多的时候手动点会累死,可以用 GitLab API 写脚本批量导出。大致流程是:

  1. 用GET /api/v4/projects?per_page=100列出所有项目。
  2. 对每个项目调用POST /api/v4/projects/:id/export触发导出。
  3. 轮询GET /api/v4/projects/:id/export/download直到状态为finished,然后下载导出文件。
  4. 在新实例上调用POST /api/v4/projects/import上传导出文件并触发导入。

这里要注意的是,项目导出包会包含 LFS 对象和容器镜像,体积可能非常大。如果项目启用了 Git LFS,要确保磁盘空间足够,同时在导出时看清楚是否包含 LFS objects。我遇到过导出文件 10GB,结果内网带宽只有 100M,传输时间比想象中长很多,最好在业务低峰期做。

4.4 迁移后的验证清单

迁移完成不等于结束。我会在新实例上逐个验证以下内容:

  • 用git clone拉取几个代表性项目的代码,确认 HTTP 和 SSH 两种协议都正常。
  • 检查分支、标签、合并请求列表是否完整。
  • 随机打开一个 Issue,确认评论和附件还在。
  • 检查项目成员列表和权限,和旧实例对照。
  • 手动触发一条 Pipeline,确认 Runner 能正常接受任务。
  • 检查 Webhook 配置是否还在,必要时重新填写内网回调地址。
  • 确认 SSH 公钥在用户设置里仍然存在。

有一次我因为忽略了 SSH 公钥,结果用户反馈“所有项目都拉不下来”,一查才发现用户的 SSH key 在旧实例上存在,但新实例的用户信息是从备份恢复的,理论上应该没问题。最后还是gitlab-rake gitlab:check跑了一遍,才发现是authorized_keys文件没有正确生成。重启gitlab-ctl reconfigure后重新生成,问题才解决。

5. http_proxy 环境影响下的特有配置

5.1 先搞清楚哪里需要走代理

公司网络里最常见的限制是:服务器只有通过内网代理服务器才能访问外网,DNS 能解析,但 TCP 出口被封。这种情况下,yum 需要代理,GitLab 安装包需要代理,GitLab 自身对外发起的请求也需要代理。

但注意一个点:代理配置是分层的,不是配一次就全搞定。系统全局的代理变量只影响你从 shell 里发起的命令,不会自动影响 yum、不会自动影响 GitLab 后台进程,更不会自动影响用户电脑上的 Git 客户端。所以要把这套环境拆成四层分别配置:

  • 操作系统层(yum、wget、curl)
  • GitLab 安装阶段(rpm 包下载、依赖解析)
  • GitLab 运行阶段(出站请求、Webhook)
  • 用户客户端(Git clone 走 HTTP/HTTPS)

5.2 安装阶段怎么让安装过程走代理

第一种方式,临时在当前 shell 设置环境变量,只对当前会话生效。适合一次性操作,不会污染系统其他用户:

export http_proxy=http://proxy.internal.example.com:3128 export https_proxy=http://proxy.internal.example.com:3128 export no_proxy=localhost,127.0.0.1,.internal.example.com

注意 GitLab 官方 rpm 包下载可能还涉及 yum 依赖。只设置环境变量的话,yum 不一定认。所以更可靠的做法是把代理写进/etc/yum.conf,这样所有 yum 相关操作都会走代理,包括安装 gitlab-ce 时解析依赖包。

另外,如果你们内网的代理需要认证,很多运维初学时会在命令里直接写用户名密码,比如:

export http_proxy=http://user:password@proxy.internal.example.com:3128

短期应急没问题,但命令会被记录在 history 里,有泄露风险。建议在~/.bashrc或/etc/profile.d/下写一个统一脚本,用环境变量引用认证信息,并限制文件权限。

5.3 GitLab 自身的出站代理配置

GitLab 安装完以后,它内部有很多后台进程需要主动访问外网。比如导入远程仓库、执行 Webhook、拉取外部依赖、更新 Geo 相关数据等。这些进程在系统服务层运行,不会读你 shell 里的http_proxy环境变量。需要在 GitLab 的全局配置文件里单独声明环境变量。

打开/etc/gitlab/gitlab.rb,添加或修改:

gitlab_rails['env'] = { "http_proxy" => "http://proxy.internal.example.com:3128", "https_proxy" => "http://proxy.internal.example.com:3128", "no_proxy" => "localhost,127.0.0.1,.internal.example.com" } gitlab_workhorse['env'] = { "http_proxy" => "http://proxy.internal.example.com:3128", "https_proxy" => "http://proxy.internal.example.com:3128", "no_proxy" => "localhost,127.0.0.1,.internal.example.com" }

gitlab_rails['env']影响的是 GitLab Rails 主进程、Sidekiq 后台任务等;gitlab_workhorse['env']影响的是负责 HTTP 请求转发的 Workhorse 进程。有些场景下如果不改 Workhorse,外部导入请求仍然会报连接超时,所以两个都应该配。

改完执行:

gitlab-ctl reconfigure gitlab-ctl restart

这里有个坑:reconfigure会重新生成 systemd 或 init 脚本,但不会总是自动重启所有进程。我一开始只 reconfigure 忘了 restart,接口看起来正常,但 Sidekiq 仍然没有加载新的代理环境变量,Webhook 死活发不出去。后来手动重启全服务才生效。

5.4 客户端侧和 SSH 场景怎么处理

用户桌面端的 Git 操作也得走代理。很多用户只知道在 GitLab 网页上能看代码,但 clone 命令半天没反应,就是因为他本机的 Git 没配代理。

对 HTTP/HTTPS 协议,让用户在自己机器上执行:

git config --global http.proxy http://proxy.internal.example.com:3128 git config --global https.proxy http://proxy.internal.example.com:3128 git config --global http.noProxyFor "localhost,127.0.0.1,.internal.example.com"

注意http.noProxyFor这个配置项名要写对,不同 Git 版本可能略有差异。老版本可以用环境变量NO_PROXY代替,但个人客户端还是建议用 Git 自身的http.proxy配置,别去改用户系统全局变量。

SSH 协议走代理相对麻烦。因为 SSH 默认走 22 端口,公司网络如果只开放了 80/443 给代理服务器,那 SSH 连接通常会失败。这时可以把 SSH 流量通过 HTTP 代理的 CONNECT 方法转发。需要在用户~/.ssh/config里加类似配置:

Host gitlab.internal.example.com HostName gitlab.internal.example.com Port 22 ProxyCommand connect -H proxy.internal.example.com:3128 %h %p

但前提是客户端机器上安装了connect这个工具,而且代理服务器允许 CONNECT 到 22 端口。如果你们公司的代理策略不允许,那只能让用户统一走 HTTPS 协议访问 GitLab,别再用 SSH 方式。我这次迁移后就把 SSH 端口从 22 改到了内网直连可达的 22022,同时在配置里告诉用户尽量用 HTTPS 克隆,省得一堆人卡在 SSH 超时上。

6. 部署和迁移中的常见问题与排查

6.1 安装卡住或报错

错误现象一:gitlab-ctl reconfigure执行到某个 recipe 时卡住不动,十几分钟没有输出。最常见原因是内存不足,GitLab 配置过程要启动 PostgreSQL 和 Redis,内存不够会导致进程反复重启。解决办法是先给服务器加 swap:

fallocate -l 4G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo '/swapfile none swap defaults 0 0' >> /etc/fstab

错误现象二:Error executing action run on resource 'ruby_block[directory resource]'。这种多半是/var/opt/gitlab目录权限错乱。检查属主是不是git:git,必要时手动修正:

chown -R git:git /var/opt/gitlab gitlab-ctl reconfigure

还有一种很隐蔽:服务器上装了安全软件,把gitlab-ctl在/opt/gitlab/embedded目录下生成的二进制文件当成可疑进程给杀了。遇到莫名其妙的服务起不来,先看/var/log/messages有没有进程被 kill 的记录,再决定是否把/opt/gitlab加白名单。

6.2 迁移后代码可看不可拉

现象是网页上能看到代码文件,但git clone报 401 或 403。这种通常不是仓库迁移丢了,而是访问凭据问题。

先分协议排查:

  • HTTP 克隆报 401:确认用户密码或 Access Token 是否有效。GitLab 新版本默认不推荐用用户密码直接 clone,改成 Personal Access Token 更安全。
  • SSH 克隆报 Permission denied:先检查用户的 SSH key 是否在新实例上存在。可以用ssh -T git@gitlab.internal.example.com测试,返回Welcome to GitLab, @username才正常。
  • 如果报repository not found,但网页上看得到仓库,很可能是当前登录用户不在该项目的成员列表里,或者项目处于 private 状态而 Token 没有相应权限。

如果有导入的项目存在“项目可见性被重置”的情况,也要检查一遍。

6.3 代理配了但 Webhook 还是不生效

这种情况我遇到过两次,每次都是看似配好了,实际没生效。

第一次是忽略了no_proxy。GitLab 后台进程访问外部地址时,如果目标地址域名正好匹配了某个“不走代理”的白名单,或者没有正确放行内网地址,Webhook 请求就卡在路由选择上。排查时看/var/log/gitlab/gitlab-rails/production_json.log或sidekiq.log,重点看有没有Failed to open TCP connection to ... : No such file or directory这类网络错误。

第二次是代理只写了http_proxy,没写https_proxy。很多 Webhook 目标回调地址是https://开头,GitLab 后台进程会读https_proxy来决定是否走代理。只配置了一个,另一个协议就裸奔出网,然后被防火墙拦死。所以我在前面专门强调,http_proxy和https_proxy两个都要配。

还有一个容易被忽略的点:如果代理服务器本身有访问外网的策略限制,比如只允许 GET/POST 到特定域名,那 GitLab 发送 Webhook 的 POST 请求也可能被代理拒绝。把 GitLab 服务器所在网段加进代理放行名单,或者干脆让 GitLab 到内网 Webhook 目标走no_proxy直连,很多问题就解决了。

7. 最后说几句我的实操心得

折腾完这套 CentOS 7.9 上的 GitLab CE 部署和迁移,我最大的感受是:迁移工作百分之八十的时间不是在执行命令,而是在确认一致性。版本一致、秘钥一致、权限一致、代理策略一致,哪一边不对,最终都会变成线上事故。

对于纯内网部署,我给几个容易忽略的细节。装完系统第一件事配置好 yum 代理,别等安装走到一半再去想代理的事。GitLab 的gitlab-secrets.json一定要跟着备份走,而且最好测试环境先恢复一遍,确认能登录再上生产。项目多的时候别图省事只git clone --mirror,那样仓库是搬过去了,但 Issue、MR、CI/CD 配置都丢了,等于搬了个空壳。

HTTP 代理环境下,最怕的不是不会配,而是配了一半。系统环境变量、yum 配置、GitLab env、用户 Git 配置四层都要覆盖。写配置前先画清楚哪些流量的源、目标、协议是什么,再决定哪些走代理、哪些放直连。尤其注意no_proxy里的内网域名,别把 GitLab 服务器访问自己内部地址的流量也稀里糊涂丢给代理,轻则慢,重则直接断连。

如果你接下来也要做同样的迁移,我强烈建议先在测试环境完整演练一遍,把所有版本差异、工具缺失、代理限制都趟平了,再挑一个业务低谷窗口正式开工。迁移这种事,慢就是快,稳就是赢。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 8:12:06

网页文件批量打印工具绿色版:一键队列与自动化实战

简介&#xff1a;这是一款面向需要频繁打印网页内容的办公人员、教师及资料整理者的绿色版批量打印工具&#xff0c;免安装即可运行&#xff0c;能一次性选中多个网页文件完成打印&#xff0c;省去逐个打开、手动操作的繁琐流程&#xff0c;在报告整理、资料汇总、教学材料制作…

作者头像 李华
网站建设 2026/10/13 8:09:58

以太坊三棵树:状态树、交易树与收据树原理与实战

1. 这不是教科书里的“树”&#xff0c;而是以太坊真正运转的骨架你打开一个以太坊区块浏览器&#xff0c;看到某笔交易状态为“成功”&#xff0c;账户余额从0.5 ETH变成0.49999999999999994 ETH——这个看似微小的数字变化&#xff0c;背后没有数据库UPDATE语句&#xff0c;没…

作者头像 李华
网站建设 2026/10/13 8:08:59

Claude+Codex+Grok组合:AI编程流水线分工协作实战指南

先说一个有点反直觉的结论&#xff1a;单论代码生成能力&#xff0c;Claude、Codex、Grok 这三个工具里没有任何一个能在所有维度碾压对手&#xff0c;但把它们按正确顺序串成一条流水线之后&#xff0c;效果确实称得上“王炸”。 这个组合解决的是我一个人维护多个项目的真实…

作者头像 李华
网站建设 2026/10/13 8:08:59

Unity UI Batch优化实战:从DrawCall暴涨到合批原理与落地规范

1. 从一次DrawCall暴涨说起&#xff1a;为什么UI合批值得死磕 做过Unity项目的人大概都经历过这种场景&#xff1a;游戏在编辑器里跑得好好的&#xff0c;一上真机帧率就往下掉&#xff0c;Profiler一开&#xff0c;UI模块的DrawCall数字高得离谱&#xff0c;几十甚至上百。更让…

作者头像 李华
网站建设 2026/10/13 8:08:50

PenguinHarness 0.2.1:一句话生成AI Agent,告别手搓胶水代码

1. 从“手搓 Agent”到一句话生成&#xff1a;PenguinHarness 0.2.1 到底改了什么如果你最近半年在折腾 AI Agent&#xff0c;大概率经历过这样的场景&#xff1a;为了让一个 Agent 能查天气、读文件、调接口&#xff0c;你写了三百行胶水代码&#xff0c;调试了两天&#xff0…

作者头像 李华
网站建设 2026/10/13 8:08:17

Claude+Codex+Grok三AI协作编程,打造高效开发流水线

说真的&#xff0c;这套组合我第一次完整跑通的那个下午&#xff0c;整个人坐在工位上是有点恍惚的——一个拖了两周没敢动的老项目改造&#xff0c;我用 Claude Codex Grok 三个人体分工打配合&#xff0c;一个下午把方案、代码、自测、踩坑记录全部收完。那种感觉就是标题里…

作者头像 李华