250829-Gitlab数据备份与恢复

在这里插入图片描述


下面给你一份可落地的迁移方案,保证 GitLab 的数据和配置完整迁移到服务器 B。你当前用的是 GitLab Omnibus(docker 版),数据都在你映射的 3 个目录里(/etc/gitlab, /var/log/gitlab, /var/opt/gitlab),迁移就是把这些目录搬过去,然后用同版本镜像在 B 上启动即可。


方案 A:直接拷贝挂载卷(最简单、最稳妥)

适合:两台机子都能互通 SSH,短暂停机可接受。

1) 在 A 上停 GitLab,确保数据静止

# 看容器名
docker ps
# 停
docker stop gitlab
# 确认都停了(也避免有自动重启)
docker update --restart=no gitlab

2) 打包或 rsync 同步 3 个目录到 B

任选其一(rsync 或 tar),二选一即可

方式一:rsync(推荐,能保留权限/硬链接)

# 在 A 上执行,把整个 gitlab 目录同步到 B
rsync -aHAX --numeric-ids --info=progress2 -e ssh \/home/liuguokai/docker/data/gitlab/ \user@服务器BIP:/home/liuguokai/docker/data/gitlab/

方式二:tar 打包

# A 上打包
sudo tar -C /home/liuguokai/docker/data/gitlab -cpf /tmp/gitlab-volumes.tar etc log opt
# 传到 B
scp /tmp/gitlab-volumes.tar user@服务器BIP:/tmp/
# B 上解包到相同路径
sudo mkdir -p /home/liuguokai/docker/data/gitlab
sudo tar -C /home/liuguokai/docker/data/gitlab -xpf /tmp/gitlab-volumes.tar

说明:一定要保留文件权限/属主(-aHAX --numeric-ids 或 tar 的 -p)。

3) 在 B 上用同一版本镜像启动

建议先在 A 上看用的镜像 tag(避免“latest”漂移导致版本不一致):

# A 上查看容器使用的镜像名:tag
docker inspect gitlab --format '{{.Config.Image}}'
# 例如得到:gitlab/gitlab-ce:16.11.2-ce.0  (示例)

然后在 B 上拉取同版本并启动(端口可按需改):

# B 上
docker pull gitlab/gitlab-ce:你的准确版本tagdocker run -itd \-p 5004:80 \-p 5005:22 \-v /home/liuguokai/docker/data/gitlab/etc:/etc/gitlab \-v /home/liuguokai/docker/data/gitlab/log:/var/log/gitlab \-v /home/liuguokai/docker/data/gitlab/opt:/var/opt/gitlab \--restart always \--privileged=true \--name gitlab \--shm-size 1g \gitlab/gitlab-ce:你的准确版本tag

4) 首次启动检查与收尾

# 跟日志,等服务健康
docker logs -f gitlab
  • 如果 B 的访问地址/域名变了,修改 /etc/gitlab/gitlab.rb 里的 external_url,然后:

    docker exec -it gitlab bash -lc "gitlab-ctl reconfigure && gitlab-ctl restart"
    
  • 验证:Web 能打开、项目可拉取/推送、CI pipeline 能跑、SSH 端口(你是 5005)能连。


方案 B:使用 GitLab 内建备份/恢复(适合跨大版本或想最小化拷贝量)

会多一步“备份→恢复”,但也很正规。同样需要备份 gitlab-secrets.jsongitlab.rb

1) 在 A 上创建应用级备份

# 停应用前先做一次在线备份也可以;若严格一致性,先 stop 再备份
docker exec -t gitlab gitlab-backup create
# 也可用:docker exec -t gitlab gitlab-rake gitlab:backup:create

备份文件会在容器内 /var/opt/gitlab/backups/,你映射到了宿主 /home/liuguokai/docker/data/gitlab/opt/backups/。同时单独备份

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

2) 把备份文件和两个配置文件复制到 B

# 例如:
scp /home/liuguokai/docker/data/gitlab/opt/backups/*_gitlab_backup.tar user@B:/tmp/
scp /home/liuguokai/docker/data/gitlab/etc/gitlab.rb user@B:/tmp/
scp /home/liuguokai/docker/data/gitlab/etc/gitlab-secrets.json user@B:/tmp/

3) 在 B 上启动干净容器(同版本),再恢复备份

# 先启动空实例(用你习惯的挂载路径)
docker run -itd \-p 5004:80 -p 5005:22 \-v /home/liuguokai/docker/data/gitlab/etc:/etc/gitlab \-v /home/liuguokai/docker/data/gitlab/log:/var/log/gitlab \-v /home/liuguokai/docker/data/gitlab/opt:/var/opt/gitlab \--restart always --privileged=true --name gitlab --shm-size 1g \gitlab/gitlab-ce:你的准确版本tag# 将备份和配置放到对应卷里
mv /tmp/*_gitlab_backup.tar /home/liuguokai/docker/data/gitlab/opt/backups/
mv /tmp/gitlab.rb /home/liuguokai/docker/data/gitlab/etc/
mv /tmp/gitlab-secrets.json /home/liuguokai/docker/data/gitlab/etc/# 执行恢复(文件名按实际改)
docker exec -it gitlab bash -lc '
gitlab-ctl stop puma && gitlab-ctl stop sidekiq
gitlab-backup restore BACKUP=备份文件名前缀(例如 1724839200_2025_08_28_16.11.2)
gitlab-ctl reconfigure
gitlab-ctl restart
'

注意:恢复必须使用相同或兼容版本(通常“同一小版本”最保险)。


关键注意事项(无论用 A 还是 B)

  1. 版本一致:先确认 A 上镜像 tag,再在 B 上用同一 tag 启动。避免“latest”自动升级导致恢复失败。

  2. 停机窗口:为避免数据写入丢失,最终迁移前要停容器再做最后一次 rsync/备份。

  3. 权限与 SELinux:拷贝要保留权限/属主(前文参数已包含)。如果 B 开了 SELinux,必要时:

    # 例如在基于 RHEL 的系统
    sudo chcon -R -t container_file_t /home/liuguokai/docker/data/gitlab
    
  4. 端口与防火墙:B 上放行你映射的 80→5004 和 22→5005(SSH for Git over SSH),以及域名解析。

  5. external_url:地址/端口变动后,记得更新 /etc/gitlab/gitlab.rbexternal_urlgitlab-ctl reconfigure

  6. Runner 与 CI/CD:注册 token、变量都在 DB 里,随数据一起迁移。Runner 机器本身不迁移,需要它们重新连到新的 URL/IP(通常无需重新注册,取决于网络与证书变化)。

  7. 证书:若用自签或自管证书,证书/私钥通常位于 /etc/gitlab/ssl/var/opt/gitlab/gitlab-rails/etc,随卷一起带走即可。


迁移后自检清单

  • Web 首页可打开,登录正常
  • 项目仓库能 git clone/push(HTTP 和 SSH)
  • CI Pipeline 能触发、Runner 正常执行
  • 容器日志无报错:docker logs -f gitlab
  • 备份目录自动轮转正常(如果你有设置)

如果你告诉我 A 上的具体镜像 tag、B 上系统与目录、以及新外网访问方式(是否换域名/端口/HTTPS),我可以把上述命令替换成你的实际值,给你一版“复制即用”的脚本。


明白了:B 机用的是 root 权限安装的新版本 Docker,账号是 dev,而且你可以把 GitLab 镜像以 tar 方式 docker load。下面给你一套从 A → B的完整步骤(含“镜像 tar 迁移”与“应用备份恢复”两块)。按顺序执行即可。


在服务器 A(rootless 环境)

容器内路径 + docker cp 绕过宿主机卷权限问题。

1) 确认镜像版本并导出镜像 tar

# 记下 GitLab 镜像 tag
docker inspect gitlab --format '{{.Config.Image}}'
# 假设输出:gitlab/gitlab-ce:16.11.2-ce.0
IMG_TAG="gitlab/gitlab-ce:16.11.2-ce.0"# 保存镜像为 tar(给 B 机 docker load 用)
docker save -o ~/gitlab-ce-16.11.2-ce.0.tar ${IMG_TAG}

2) 暂停写入并做 GitLab 应用备份

docker exec -it gitlab bash -lc 'gitlab-ctl stop sidekiq && gitlab-ctl stop puma'
docker exec -t gitlab gitlab-backup create
docker exec -t gitlab bash -lc 'ls -lh /var/opt/gitlab/backups/'
# 记住备份文件名,比如:1724908800_2025_08_29_16.11.2_gitlab_backup.tar

3) 用 docker cp 拷出备份与关键配置

# 备份包
docker cp gitlab:/var/opt/gitlab/backups/1724908800_2025_08_29_16.11.2_gitlab_backup.tar ~/ # 必须的两个配置
docker cp gitlab:/etc/gitlab/gitlab.rb ~/ 
docker cp gitlab:/etc/gitlab/gitlab-secrets.json ~/# 如启用 HTTPS,连同证书拷出(如存在)
docker cp -a gitlab:/etc/gitlab/ssl ~/ssl# 如本地启用 Container Registry(非对象存储),一并打包:
docker exec -it gitlab bash -lc 'if [ -d /var/opt/gitlab/registry ]; then tar -C /var/opt/gitlab -cpf /tmp/registry.tar registry; fi'
docker cp gitlab:/tmp/registry.tar ~/ 2>/dev/null || true

4) 传到 B

scp ~/gitlab-ce-16.11.2-ce.0.tar dev@B:/home/dev/
scp ~/*gitlab_backup.tar dev@B:/home/dev/
scp ~/gitlab.rb ~/gitlab-secrets.json dev@B:/home/dev/
[ -d ~/ssl ] && scp -r ~/ssl dev@B:/home/dev/
[ -f ~/registry.tar ] && scp ~/registry.tar dev@B:/home/dev/

(可选)恢复 A 上的服务:

docker exec -it gitlab bash -lc 'gitlab-ctl start puma && gitlab-ctl start sidekiq'

在服务器 B(rootful Docker,用户 dev)

0) 让 dev 能用 docker(如尚未做)

sudo usermod -aG docker dev
# 重新登录 shell(或 newgrp docker)后再继续

1) 准备目录 & 载入镜像 tar

BASE="/home/dev/docker/data/gitlab"
mkdir -p ${BASE}/{etc,log,opt,opt/backups}# 加载镜像 tar(或直接 docker pull 同版本也可以)
docker load -i /home/dev/gitlab-ce-16.11.2-ce.0.tar

2) 启动“空” GitLab 容器(同版本)

IMG_TAG="gitlab/gitlab-ce:16.11.2-ce.0"
docker run -itd \-p 5004:80 \-p 5005:22 \-v ${BASE}/etc:/etc/gitlab \-v ${BASE}/log:/var/log/gitlab \-v ${BASE}/opt:/var/opt/gitlab \--restart always \--privileged=true \--name gitlab \--shm-size 1g \${IMG_TAG}# 等 1~2 分钟让它初始化目录结构(可跟日志观察)
docker logs -f gitlab | sed -n '1,120p'

3) 放入 A 的备份与配置(必要时先编辑 external_url)

# 放备份
mv /home/dev/*gitlab_backup.tar ${BASE}/opt/backups/# 放配置与密钥(覆盖空实例的文件)
mv /home/dev/gitlab.rb ${BASE}/etc/
mv /home/dev/gitlab-secrets.json ${BASE}/etc/# 如有证书
[ -d /home/dev/ssl ] && mv /home/dev/ssl ${BASE}/etc/# 如有 Registry 数据(本地存储)
[ -f /home/dev/registry.tar ] && tar -C ${BASE}/opt -xpf /home/dev/registry.tar# 如果 B 要改访问地址/端口/协议,请编辑 external_url
# 例如:
# sed -i 's|^external_url .*|external_url "http://<B的IP或域名>:5004"|' ${BASE}/etc/gitlab.rb

权限提示:B 是 rootful Docker,卷中文件即使属于 dev 也没关系;容器内是 root,能正常读写。如需“更像原生”,可:

sudo chown -R root:root ${BASE}/{etc,log,opt}

4) 恢复备份

# 停写
docker exec -it gitlab bash -lc 'gitlab-ctl stop sidekiq && gitlab-ctl stop puma'# 取备份前缀(去掉结尾 _gitlab_backup.tar)
docker exec -it gitlab bash -lc 'ls -1 /var/opt/gitlab/backups'# 假设前缀是 1724908800_2025_08_29_16.11.2
docker exec -it gitlab bash -lc 'yes yes | gitlab-backup restore BACKUP=1724908800_2025_08_29_16.11.2'

5) reconfigure & restart

docker exec -it gitlab bash -lc 'gitlab-ctl reconfigure && gitlab-ctl restart'

验证与收尾

# 日志
docker logs -f gitlab# Web 访问
# http://<B的IP或域名>:5004  (如配置了 https 则用 https)# Git over HTTP/SSH
git ls-remote http://<B>:5004/namespace/project.git
git ls-remote ssh://git@<B>:5005/namespace/project.git# CI/CD & Runner
docker exec -it gitlab bash -lc 'gitlab-ctl status'
# 触发 pipeline;如更换了域名/证书,Runner 端按需更新 URL/证书信任

小贴士 / 踩坑预防

  • 镜像架构要一致(A、B 同为 amd64 或同为 arm64);否则用 docker pull 官方多架构镜像更稳。
  • 保持版本一致(你已用镜像 tar;若用 pull 也请用相同 tag)。
  • Container Registry 如走对象存储则无需搬数据;如本地存储务必随同迁移。
  • 防火墙/安全组 放行 5004(HTTP/HTTPS 反代后视情况)和 5005(SSH for Git)。
  • external_url 变更 后一定要 gitlab-ctl reconfigure

如果你把在 A 机生成的备份文件名(完整或“前缀”)贴出来,我可以把 B 机的 BACKUP= 命令替换成你的实际值,给你一版可直接粘贴执行的命令。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/920753.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/920753.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

吴恩达机器学习作业十一:异常检测

数据集在作业一异常检测异常检测就是发现与大部分对象不同的对象&#xff0c;其实就是发现离群点。异常检测有时也称偏差检测。异常对象是相对罕见的。用数据集建立概率模型p ( x )&#xff0c;如果新的测试数据在这个模型上小于某个阈值&#xff0c;则说它极大可能为异常点算法…

2000w 的数据量,mysql要进行几次IO操作,为什么

在 MySQL 中&#xff0c;2000 万数据量的表在进行查询时所需的 ​​IO 操作次数​​主要取决于 ​​索引结构&#xff08;B树层级&#xff09;​​、​​查询类型​​和 ​​数据分布特征​​。以下是具体分析&#xff1a;一、B树层级与 IO 次数的关系InnoDB 引擎通过 B树索引管…

【代码随想录day 22】 力扣 39. 组合总和

视频讲解&#xff1a;https://www.bilibili.com/video/BV1KT4y1M7HJ/?vd_sourcea935eaede74a204ec74fd041b917810c 文档讲解&#xff1a;https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html#%E6%80%9D%E8%B7%AF 力扣题目&#xff1a;https://leetcod…

DrissionPage 实战:动态 IP 代理与百度翻译 API 数据抓取

本文将详细介绍如何使用 DrissionPage 实现动态 IP 代理访问&#xff0c;并结合百度翻译 API 进行数据抓取与处理。一、技术选型与架构设计1.1 为什么选择 DrissionPage&#xff1f;DrissionPage 作为新一代网络自动化工具&#xff0c;相比传统 Selenium Requests 方案具有显著…

策略模式:灵活应对算法动态切换

引言 在软件开发中&#xff0c;我们常常会遇到需要在运行时动态选择和切换算法或行为的场景。例如&#xff0c;电商系统中的多种支付方式、游戏中的不同难度设置&#xff0c;或是计算器中的各种运算符。传统的方法可能会使用复杂的条件判断语句&#xff08;如if-else或switch-c…

【C++ 】string类:深拷贝与浅拷贝解析

【C 】string类操作全解析-CSDN博客 1.stirng类的模拟实现 1.1 经典的string类问题 上面已经对string类进行了简单的介绍&#xff0c;大家只要能够正常使用即可。在面试中&#xff0c;面试官总喜欢要求自己来模拟实现string类&#xff0c;最主要是实现string类的构造、拷贝…

Decoder 解码器

Decoder 解码器&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h>#include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libswscale/swscale.h>#define WORD uint16_t #define DWORD ui…

globals() 小技巧

scheduler_class globals()[scheduler_class_name] Python 中一种 动态获取类对象 的常用技巧&#xff0c;属于 反射&#xff08;reflection&#xff09; 编程的范畴globals()Python 内置函数&#xff0c;返回一个 字典&#xff08;dict&#xff09;&#xff0c;包含当前模块&…

Android Studio 9.png制作

一、新建 二、把要做的图png导入进去 png图片建议 根据内容预留1像素可拉伸区域 eg:纯色或可渐变底色 三、右边创建.9.png 四、双击打开 1、绘制黑边 参考视频 2、缩放到800% ,移至右下 3、在下面和右边绘制整根黑线 4、根据png 位置左侧和上侧黑线 4.1 分析 红色方框为…

【百度】C++开发(25届提前批 一面)面经

文章目录1. 代码实现&#xff1a;说说LRU&#xff0c;并代码实现LRU为什么使用哈希表&#xff1f;&#xff08;有两个原因&#xff09;1. 仅用双向链表的缺陷2. 引入哈希表的作用1. 快速查找&#xff1a;2. 快速插入与删除&#xff1a;双向链表 哈希表的协作过程举例说明代码实…

Word文档怎么打印?Word打印技巧?【图文详解】单面/双面/指定页面/逆序等Word打印选项

一、问题背景 在日常办公、学习场景中&#xff0c;Word文档作为常用的文字处理载体&#xff0c;经常需要将电子内容转化为纸质版本&#xff0c;比如提交报告、打印学习资料、整理文档存档等。 但不少用户在尝试打印Word文档时&#xff0c;常会遇到各种阻碍&#xff1a;有的不清…

漫谈《数字图像处理》之基函数与基图像

在数字图像处理领域&#xff0c;基函数与基图像是贯穿理论分析与实际应用的核心概念 —— 它们如同 “乐高积木”&#xff0c;将复杂的图像信号拆解为可解释、可操作的基本单元&#xff0c;支撑起压缩、去噪、特征提取等一系列关键任务。从传统的傅里叶变换到前沿的因子场理论&…

打开多个Excel文件后快速关闭所有的文档,并且退出Excel应用

打开多个Excel文件后如果要快速关闭所有的文档&#xff0c;并且退出Excel应用&#xff0c;可以按住Shift键右上角的号&#xff08;关闭按钮&#xff09;。Word和PowerPoint也是一样的操作。如果有文档修改后没有保存&#xff0c;会提示是否保存。作为补充&#xff0c;先来看看两…

基于 PyTorch 构建 Dataset 与 DataLoader:从 TXT 文件读取到新增类别全流程指南

基于 PyTorch 构建 Dataset 与 DataLoader&#xff1a;从 TXT 文件读取到新增类别全流程指南在深度学习计算机视觉任务中&#xff0c;数据加载与预处理是模型训练的基础环节&#xff0c;直接影响模型的训练效率与最终性能。PyTorch 作为主流深度学习框架&#xff0c;提供了Data…

hive on tez如果是2个大表union会写几次临时文件到hdfs目录,数据量如何计算

如果是2个大表union会写几次临时文件到hdfs目录&#xff0c;数据量如何计算 在Hive on Tez中&#xff0c;两个大表执行UNION操作时&#xff0c;临时文件的写入次数和数据量&#xff0c;取决于UNION的类型&#xff08;UNION ALL还是UNION去重&#xff09;以及执行计划的Stage划分…

Web+js转uni-app+ts

一、入手uni-app 官方文档&#xff1a;uni-app官网 1.创建uni-app项目 1.1通过HBuilderX进行创建 官方地址&#xff1a;HBuilderX-高效极客技巧 1.2通过命令行创建 // js 版本的 npx degit dcloudio/uni-preset-vue#vite 项目名 npx degit dcloudio/uni-preset-vue#vite-…

IO_hw_8.29

1.使用fgets和fputs完成两个文件的拷贝&#xff0c;要求文件名使用外部传承2.注册登录代码3.思维导图4.牛客网刷题记录

数据结构(04)—— 栈和队列

Hi&#xff01;探索者们&#x1f609;&#xff0c;欢迎踏入 408 数据结构的奇妙秘境&#x1f33f;&#xff01;​ 我是 ankleless&#x1f4da;&#xff0c;和你并肩的寻宝人&#xff5e; 这是我的探险手札&#x1f5fa;️&#xff0c;里面记着链表森林的岔路陷阱&#x1f578;…

Java多线程基础:进程、线程与线程安全实战

Java多线程基础&#xff1a;进程、线程与线程安全实战 &#x1f680; 极客小贴士 &#x1f4a1; 你知道吗&#xff1f; 在Java中&#xff0c;每个线程都有自己的栈空间&#xff0c;但共享堆内存。这就像每个员工都有自己的办公桌&#xff0c;但共享公司的会议室和打印机&#…

2025 实测有效!手把手教你如何用实例代码(Python、JavaScript 、JAVA) 等实战代码,免费股票数据接口大全

​ 近年来&#xff0c;股票量化分析凭借其科学性与系统性&#xff0c;逐渐走进大众视野并受到广泛关注。对于这一领域的初学者而言&#xff0c;入门路上的第一道关卡便是如何获取全面且精准的股票数据。要知道&#xff0c;实时交易数据、历史交易记录、财务数据以及基本面信息等…