拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Ubuntu 24.04下用Docker Compose部署GitLab与MySQL 8.0实战

1. 部署环境准备Ubuntu 24.04 的初始化细节1.1 版本选择与系统配置建议聊到 Ubuntu 2024其实就是 Ubuntu 24.04 LTSNoble Numbat2024 年 4 月发布整整五年支持作为 GitLab MySQL 这种自托管服务的底座非常合适。如果你手头机器还是 22.04 LTS也不用着急下面这套方案在 22.04 上同样能跑核心逻辑完全一致只有 Docker 软件源的代号需要微调。我建议你在部署之前先用几个命令把机器底子摸清楚lsb_release -a uname -m free -h df -h /这里面最容易被忽略的是架构。绝大多数服务器是 x86_64但如果你用的是树莓派、飞腾或者一些 ARM 云主机后面的 Docker 镜像拉取、Docker Compose 二进制下载都得换成 arm64 版本这一步提前确认能省掉后面一半的排错时间。GitLab 是个吃内存大户官方最低建议是 4GB 内存跑一个最小化实例配上 MySQL 8.0 之后我个人建议至少 4GB8GB 以上更稳。如果机器只有 2GB后面我会单独讲怎么通过关闭 GitLab 内置组件和加 swap 来续命。1.2 基础软件包与 apt 源处理新机器到手第一件事不是急着装 Docker而是把系统基础环境理顺。我先装一批后面用得到的工具顺手把 apt 源调成国内源。这里不是崇洋媚外纯粹是实测下来在部分区域默认源拉包的体验确实不稳定换源后apt update速度快了不止一个量级。sudo apt update sudo apt install -y curl wget vim net-tools ca-certificates gnupg lsb-release换源的话直接编辑/etc/apt/sources.list把archive.ubuntu.com和security.ubuntu.com换成mirrors.ustc.edu.cn或者mirrors.tuna.tsinghua.edu.cn都可以。24.04 的源文件里可能是带Ubuntu-Sources的 deb822 格式路径在/etc/apt/sources.list.d/ubuntu.sources操作方法略有区别就不展开贴全文了你搜一下Ubuntu 24.04 换源就有现成模板。还有一个容易忽略的点如果你的服务器是刚开的云主机建议先把unattended-upgrades的行为看清楚有时候半夜系统自动更新内核第二天 Docker 容器老出幺蛾子。我一般直接把自动更新关掉改成手动维护窗口升级sudo dpkg-reconfigure unattended-upgrades选择不启用即可。1.3 端口规划80、443、2222 到底谁用GitLab 默认占用 80 和 443因为网页访问、Git HTTP(S) 克隆都要走这俩端口。宿主机上的 22 端口如果已经被 SSH 占了容器里的 22GitLab 内置 SSH就映射不出来所以需要把宿主机的 2222 映射到容器的 22。我实际部署时把端口规划固定成下面这样宿主机端口容器端口用途说明8080GitLab HTTP 访问如果被 Nginx 占用改成 8080443443GitLab HTTPS 访问暂不用 HTTPS 可保留不映射222222GitLab SSH 克隆避免和宿主机 SSH 冲突33073306MySQL 端口建议不要暴露到公网这里多说一句如果你不想让 MySQL 对公网开放强烈建议不要映射3306:3306或者只映射到127.0.0.1:3307:3306。GitLab 容器访问 MySQL 走的是 Docker 内部网络根本不需要从宿主机暴露端口出来端口映射给外部工具临时连库用的。2. Docker 与 Docker Compose 的安装以及离线场景怎么救2.1 Docker Engine 在线安装的推荐方式Ubuntu 自带 apt 源里的docker.io版本普遍偏老Compose 插件也未必齐全所以我还是推荐走 Docker 官方 apt 源装 Docker Engine。步骤不长但每一步都有讲究# 1. 添加 Docker 官方 GPG 密钥 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg # 2. 添加软件源 echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 3. 安装 sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugindocker-compose-plugin装完以后系统里就有 Compose v2 了命令是docker compose注意中间有空格和老的docker-compose不是一回事。现在新项目我统一用 v2 语法。装完先把服务拉起来并设置开机自启sudo systemctl enable docker --now docker version docker compose version2.2 配置镜像加速Docker Hub 在国内访问时有时会拽不动大镜像GitLab 的镜像动辄两三个 GB拉取超时非常痛苦。这时候在/etc/docker/daemon.json里配置加速器是常规操作{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn ] }注意加速器地址有很多有的需要你在云服务商控制台申请专属地址有的是公共镜像站。加完以后sudo systemctl restart docker然后验证docker info | grep -A 2 Registry Mirrors能看到你配置的地址就算生效了。拉取镜像慢的问题这一下就能改善不少。2.3 离线安装 Docker 和 Compose 的保姆式步骤生产环境经常遇到内网机没外网权限这时候装 Docker 就是另一套玩法。这套离线方案也是我们实际踩过不少坑才理清的。先在一台能联网的同架构机器上从 Docker 官方 apt 源把几个 deb 包下载下来apt download docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin如果怕漏依赖用apt-get download会把当前机器的依赖也算进去但目标机器可能有差异。稳妥的做法是直接去清华或者中科大的 docker-ce 仓库手动下载对应发行版代号和架构的包https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu/dists/noble/pool/stable/amd64/把docker-ce、docker-ce-cli、containerd.io、docker-buildx-plugin、docker-compose-plugin这几个包全拷到目标机器上然后sudo dpkg -i *.deb如果提示缺依赖直接执行sudo apt install -f -y把剩余的依赖补上就行。装完同样要验证docker version和docker compose version。离线环境下如果不想装docker-compose-plugin这个插件包也可以直接下载 Docker Compose 的独立二进制文件。去 GitHub 对应仓库的 release 页面下载docker-compose-linux-x86_64或 arm64 版本然后sudo mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose docker-compose --version这样你就得到了docker-compose老命令配置文件写法基本一致唯一的区别是执行命令时不带空格docker-compose up -d。离线环境下还有一个问题GitLab 和 MySQL 的镜像怎么搞答案是docker save和docker load。先在联网机器上拉好镜像docker pull gitlab/gitlab-ce:17.3.0-ce.0 docker pull mysql:8.0.40 docker save -o gitlab-ce.tar gitlab/gitlab-ce:17.3.0-ce.0 docker save -o mysql-8.0.tar mysql:8.0.40把两个 tar 文件拷到内网机器上然后docker load -i gitlab-ce.tar docker load -i mysql-8.0.tar需要注意docker save和docker export不一样save 出来的是完整镜像带历史层load 回去之后docker images能看到完整信息export 导出的是容器文件系统load 不能直接跑起来。这个别搞混了。3. 编排方案设计为什么 GitLab 要外置一个 MySQL 8.03.1 不跑单容器坚持 Compose 编排的理由很多教程喜欢直接docker run一条命令把 GitLab 拉起来图省事。但 GitLab 这种服务关联的数据持久化、配置管理、重启恢复靠一条docker run根本照顾不过来。我第一次搭的时候就是吃了这个亏容器删了重建数据目录还在但又不敢乱动最后整个重来。用 Docker Compose 编排的核心价值在于把两个容器的网络、数据卷、环境变量、依赖关系全部写进一个 YAML 文件任何新同事拿到文件就能复现整套环境。以后的版本升级、配置修改都是改 YAML 再执行一条命令的事。我用的服务划分是gitlabGitLab Community Edition 官方镜像mysqlMySQL 8.0 官方镜像两个容器放在同一个自定义网络里通过服务名互相访问。这样的话GitLab 连接数据库的连接串里只需要写mysql这个主机名Docker 内部的 DNS 会自动解析到 MySQL 容器。3.2 为什么不用 GitLab 内置 PostgreSQLGitLab 默认自带 PostgreSQL首次启动就会自动初始化好开箱即用。既然内置数据库这么省事为什么还要额外装一个 MySQL 8.0答案取决于使用场景。如果你只是给三五个人搭个私有 Git 仓库那内置 PostgreSQL 就挺好不需要折腾。但如果你所在的团队已经有了 MySQL 8.0 的运维规范、慢查询监控、定时备份通道GitLab 只是众多业务系统之一那让 GitLab 复用 MySQL 基础设施更符合实际情况。GitLab 官方文档确实是支持 MySQL 8.0 的只是要求使用 InnoDB 引擎、utf8mb4 字符集、MySQL 8.0.16 以上版本。把数据库独立出来之后做数据迁移、故障切换、扩缩容都更灵活。我这边选择外置 MySQL 还有一层原因监控和备份通道可以完全复用现成体系不用为 GitLab 单独再维护一套 PostgreSQL。3.3 数据卷与重启策略的规划Compose 文件里最容易搞错的是数据卷的挂载方式。GitLab 容器有四个关键目录需要持久化/etc/gitlab配置文件含密钥/var/opt/gitlab应用数据、仓库/var/log/gitlab日志MySQL 需要持久化的是/var/lib/mysql数据库文件/etc/mysql/conf.d自定义配置目录这里可放自定义 my.cnf我建议用命名卷named volume或者宿主机目录都可以我实际更倾向直接在宿主机指定一个明确的目录比如/srv/gitlab和/srv/mysql。好处是出问题的时候可以直接上宿主机看文件、备份目录不需要再去翻 Docker 卷目录。重启策略上一律用unless-stopped。这样宿主机重启后 Docker 能自动把两个容器拉起来不用人工干预。3.4 网络模型与端口映射一个容易忽略的细节两个容器在同一个 Compose 项目里默认会创建项目名的桥接网络。GitLab 访问 MySQL 走的是容器网络速度和安全性都好。外部用户访问 GitLab 只走 80/443 和 2222。这里有一个比较隐蔽的坑如果宿主机上的 80 端口已经被 Nginx 或者其他 Web 服务占了GitLab 的external_url要同步修改。比如你只能映射8080:80那external_url就得写成http://你的IP:8080否则页面上生成的克隆地址是错的用户复制下来也推不上去。同理SSH 克隆地址由gitlab_rails[gitlab_shell_ssh_port]控制。这个值必须等于宿主机映射出来的端口 2222否则 GitLab 提示克隆地址时还会是ssh://githost:22导致连接失败。4. docker-compose.yml 完整配置与逐段解读4.1 完整 YAML 文件下面这个 YAML 是我整理后的完整版直接拿去改几个密码就能用version: 3.8 services: mysql: image: mysql:8.0.40 container_name: gitlab-mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ChangeMe_Root_Pass MYSQL_DATABASE: gitlabhq_production MYSQL_USER: gitlab MYSQL_PASSWORD: ChangeMe_GitLab_Pass TZ: Asia/Shanghai command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_general_ci - --default-time-zone08:00 volumes: - /srv/mysql/data:/var/lib/mysql - /srv/mysql/conf:/etc/mysql/conf.d ports: - 127.0.0.1:3307:3306 healthcheck: test: [CMD, mysqladmin, ping, -h, localhost, -uroot, -p$$MYSQL_ROOT_PASSWORD] interval: 10s timeout: 5s retries: 10 start_period: 30s gitlab: image: gitlab/gitlab-ce:17.3.0-ce.0 container_name: gitlab restart: unless-stopped depends_on: mysql: condition: service_healthy environment: GITLAB_OMNIBUS_CONFIG: | external_url http://192.168.1.100 gitlab_rails[gitlab_shell_ssh_port] 2222 gitlab_rails[db_adapter] mysql2 gitlab_rails[db_encoding] utf8mb4 gitlab_rails[db_host] mysql gitlab_rails[db_port] 3306 gitlab_rails[db_username] gitlab gitlab_rails[db_password] ChangeMe_GitLab_Pass gitlab_rails[db_database] gitlabhq_production prometheus_monitoring[enable] false grafana[enable] false shm_size: 256m ports: - 80:80 - 443:443 - 2222:22 - 5050:5050 volumes: - /srv/gitlab/config:/etc/gitlab - /srv/gitlab/data:/var/opt/gitlab - /srv/gitlab/logs:/var/log/gitlab healthcheck: test: [CMD, curl, -fsS, http://localhost/-/readiness] interval: 30s timeout: 10s retries: 10 start_period: 300s4.2 MySQL 8.0 容器配置逐项说明MYSQL_DATABASE这个环境变量是关键MySQL 容器首次初始化数据目录时会自动创建这个库并且把MYSQL_USER和MYSQL_PASSWORD对应的账号授权到该库。GitLab 默认的数据库名就是gitlabhq_production所以这里直接指定就好不用再手动建库授权。command里的--character-set-serverutf8mb4和--collation-serverutf8mb4_general_ci是硬性要求。GitLab 连接 MySQL 时的编码必须是 utf8mb4如果用了默认的 latin1初始化数据库阶段就会报错或者出现乱码。--default-time-zone08:00按你的实际时区来不设的话 MySQL 默认 UTCGitLab 显示时间会差八个小时。healthcheck里的$$MYSQL_ROOT_PASSWORD要注意有两个$这是 Compose 的转义写法避免被宿主机环境变量提前解析。mysqladmin ping是判断 MySQL 是否可用的最直观方式这个健康检查是 GitLab 等待 MySQL 的先决条件。/srv/mysql/conf目录空着也能挂载MySQL 镜像会读取里面的.cnf文件。后续如果要调整慢查询日志、binlog 过期时间直接往里面放配置文件再重启容器就行。4.3 GitLab 容器配置逐项说明GITLAB_OMNIBUS_CONFIG是 GitLab 容器最重要的环境变量它接收一段 Ruby 配置代码首次启动时会写入/etc/gitlab/gitlab.rb然后触发gitlab-ctl reconfigure。external_url直接决定 GitLab 页面上所有链接的域名前缀。如果映射的是 80 端口写http://你的IP或者域名即可不要带端口。如果映射成了8080:80这里就要写成http://你的IP:8080。gitlab_rails[gitlab_shell_ssh_port] 2222必须和宿主机映射端口一致这样页面上生成的 SSH 克隆地址会正确带上 2222用户复制出来的地址才真正可克隆。prometheus_monitoring[enable] false和grafana[enable] false是我强烈建议加的。GitLab 默认会启动一堆监控组件对一个小团队或者个人部署来说这些组件白白吃了几百 MB 内存关掉之后整机负载能明显降下来。shm_size: 256m是给容器分配的/dev/shm大小。默认 64MB 对 GitLab 的某些操作来说太紧张反正内存够的话给 256MB 比较稳妥。depends_on用condition: service_healthy表示 GitLab 会等 MySQL 健康检查通过后才启动。否则两个容器同时起GitLab 初始化时数据库还没起来reconfigure 就会报错然后反复重试。5. 启动流程与初始化 GitLab5.1 第一次启动的时间线配置改好之后进入 Compose 文件所在目录执行docker compose up -d第一次启动拉镜像的时间取决于网络GitLab 镜像大概 2.5GB慢的时候能拉十几分钟。这里正好能看出镜像加速器有没有配置好。镜像拉完开始创建容器MySQL 一般 30 秒内就能起来。GitLab 就慢多了它的初始化要经历gitlab-ctl reconfigure这个过程会配置数据库、编译 assets、启动各个子服务通常要 5 到 10 分钟。这段时间里你访问页面只会看到 502。怎么判断 GitLab 是否就绪两种方式docker ps docker logs -f gitlabdocker ps看 STATUS 列如果健康检查通过会显示(healthy)。日志最末尾出现类似gitlab Reconfigured! gitlab Initializing...说明已经 boot 完成。用curl -I http://localhost能收到 302 跳转就说明 Web 服务已经起来了。5.2 获取 root 初始密码GitLab 首次启动时会生成一个随机密码存在容器内的/etc/gitlab/initial_root_password文件里只有 root 用户能读sudo docker exec -it gitlab cat /etc/gitlab/initial_root_password文件内容类似# WARNING: This value is valid only in the following circumstances # 1. If provided manually (either via GITLAB_ROOT_PASSWORD environment variable) # 2. Password has been changed automatically... Password: 一串随机字符在这里我是比较推荐用GITLAB_ROOT_PASSWORD环境变量直接指定初始密码的省去登录后再去容器里翻文件的麻烦也更符合自动化部署的习惯。你在environment里加一行GITLAB_ROOT_PASSWORD: YourStrongPass123!注意这个变量只在首次初始化时生效之后你再改它也不会重置密码。我建议设置一个临时强密码首次登录后再通过界面改成正式密码然后把环境变量从 Compose 文件里删掉。5.3 首次登录与必改配置浏览器打开http://你的IP用户名root密码用上面拿到的临时密码。登录成功后第一步去右上角头像 → Preferences 里改密码然后顺手把语言切换成简体中文位置在 Preferences → Localization → Language改成zh_CN后 GitLab 界面立刻变中文团队使用起来亲和力高不少。接着建议立刻创建一个测试项目验证整套链路。新建项目后按照页面提示添加 SSH Key。生成密钥的标准步骤ssh-keygen -t ed25519 -C youremailexample.com cat ~/.ssh/id_ed25519.pub把公钥内容复制到 GitLab 的 SSH Keys 设置页。然后测试克隆ssh -T -p 2222 git192.168.1.100 git clone ssh://git192.168.1.100:2222/root/test-project.git如果git clone能拉下来说明整个 GitLab 服务的 Web 层和 SSH 层都通了。这里最常见的坑就是把克隆地址里的端口看漏因为地址是ssh://githost:2222/...格式端口 2222 不能漏。5.4 MySQL 8.0 的验证与授权调整GitLab 起来后MySQL 这边也应该看一眼确认账号权限和数据初始化情况都正常docker exec -it gitlab-mysql mysql -uroot -p登录后执行SHOW DATABASES; USE gitlabhq_production; SHOW TABLES; SELECT COUNT(*) FROM schema_migrations;如果schema_migrations有几百条记录说明 GitLab 的表结构已经完整的迁移到 MySQL 里了。这套部署就算真正落地了。6. 从实际使用踩过的坑里提炼的排查清单6.1 502 页面与 CPU 跑满GitLab 刚启动时 502 是正常现象重新 configure 完成后会自动恢复。但如果等了 20 分钟还是 502就要上手查了。我的排查顺序是docker logs --tail 200 gitlab docker stats free -h df -h日志里如果反复出现puma的 worker 退出或者gitaly连接超时大概率是内存不够。GitLab 的 Puma、Sidekiq、Gitaly 都吃内存4GB 机器跑起来基本是满负荷2GB 机器就算勉强起来也会频繁 OOM。解决办法有两个方向关闭内置监控组件前面 YAML 里已经关了调整 Puma worker 数在GITLAB_OMNIBUS_CONFIG里加puma[worker_processes] 2 puma[min_threads] 4 puma[max_threads] 8如果内存实在顶不住加 swap 是最后的兜底手段sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo /swapfile none swap sw 0 0 | sudo tee -a /etc/fstab6.2 容器频繁重启的排查思路MySQL 容器起来又挂挂完又起这种问题看docker logs gitlab-mysql基本就能定位。我遇到过的几类根因宿主机磁盘写满MySQL 强制崩溃。先df -h清理/var/lib/docker下的悬空镜像和日志。数据卷权限不对容器内 mysql 用户无法写入挂载目录。宿主机执行chown -R 999:999 /srv/mysql/data。初始化数据目录后改了字符集参数MySQL 8 在数据目录初始化完成后改--character-set-server会导致启动失败必须清空数据卷重新初始化。最后一种是我最深刻的教训。第一次配 Compose 时没加字符集参数初始化完发现编码不对直接往 command 里加参数然后重启容器结果 MySQL 直接拒绝启动日志里明明白白写着Character set utf8mb4 is not a compiled character set之类的报错。最后只能把/srv/mysql/data清空重新来一遍。所以字符集参数必须在第一次启动前就定好中途改基本等于删库重建。6.3 GitLab 连接 MySQL 的认证插件踩坑MySQL 8.0 默认的认证插件是caching_sha2_password而老一些的 GitLab 版本用的 Ruby MySQL 驱动对这个插件支持得并不好连接时会报Authentication plugin caching_sha2_password cannot be loaded。后面 GitLab 版本逐步兼容了但如果你用的镜像偏老还是会踩到。处理方式也有两种。一种是 MySQL 启动命令里加--default-authentication-pluginmysql_native_password但 MySQL 8.4 里这个参数已经移除了。更好的方式是单独给 GitLab 的账号指定认证插件ALTER USER gitlab% IDENTIFIED WITH mysql_native_password BY ChangeMe_GitLab_Pass; FLUSH PRIVILEGES;我个人更建议直接升级到支持caching_sha2_password的 GitLab 版本欠的技术债早晚要还MySQL 官方对mysql_native_password的淘汰是既定路线。6.4 与 GitLab API Token 相关的连接报错热词里有一条login failed. check api token or gitlab version. log in via git if the versi这是各种外部工具对接 GitLab API 时的经典报错。常见场景是 Jenkins 或者 GitLab Runner 里填了 Personal Access Token但版本要求或者权限范围没匹配上。处理时核对三件事Token 是否还有效GitLab 页面 → Preferences → Access Tokens 里查状态Token 的 scope 是否勾选了api使用的 GitLab API 版本路径是否正确老代码写死/api/v3的换新版本基本连不上另外提一嘴如果后续要配置 GitLab Runner 做 CI/CDRunner 注册时需要的 registration token 对应着 GitLab 高危安全更新的重要一环。官方多次针对 Runner Token 机制做过调整你在界面上复制到的 token 要以你当前版本显示为准不要网上抄一个旧命令就硬套。6.5 热词里出现的高危漏洞修复GitLab 社区每隔一段时间就会发布安全版本如果你用的是命令行直接拉的最新镜像docker-compose.yml里的镜像 tag 是固定的不会自动升级。所以要主动保持镜像版本更新。具体操作后面第 7 节会讲。这里提醒一句GitLab 官方安全公告是值得订阅的高危漏洞利用往往发生在公开几天之内修复窗口越短越好。尤其是你暴露在公网上的实例别等着被扫描到才去升。7. 日常运维、备份策略与资源优化7.1 备份方案数据库要单独备份GitLab 自带备份命令docker exec -t gitlab gitlab-backup create这个命令会备份仓库、上传文件、数据库等内容输出文件在容器内的/var/opt/gitlab/backups目录也就是宿主机的/srv/gitlab/data/backups。但这里有一个很多人忽略的关键点如果你用了外置 MySQLgitlab-backup create会尝试连接你配置的 MySQL 并 Dump 数据库这部分依赖 GitLab 容器运行时能正常连上 MySQL。一旦 MySQL 容器先挂了GitLab 备份命令就会直接失败。所以更稳妥的备份方案是GitLab 数据备份和 MySQL 数据库备份分开做。docker exec -it gitlab-mysql mysqldump -uroot -pChangeMe_Root_Pass --single-transaction --routines --triggers gitlabhq_production /srv/backups/gitlab-db-$(date %F).sql同时千万不要忘了备份/srv/gitlab/config里的一堆配置文件特别是gitlab-secrets.json。这个文件里保存了 GitLab 的加密密钥丢了它之前的备份恢复到新环境时会直接失败数据库数据即使还在也没法解密。我用 crontab 做了每日备份0 2 * * * docker exec -t gitlab gitlab-backup create 2/var/log/gitlab-backup.log 10 2 * * * docker exec gitlab-mysql mysqldump -uroot -pChangeMe_Root_Pass --single-transaction gitlabhq_production | gzip /srv/backups/gitlab-db-$(date \%F).sql.gz备份恢复我用过一次从备份创建恢复到新机器上的完整链路是装好 Compose 环境起一个全新的 MySQL 容器把 sql 备份导进 MySQL把gitlab-secrets.json和gitlab.rb放回/srv/gitlab/config把gitlab-backup产生的 tar 放到备份目录启动 GitLab 容器进入容器执行gitlab-backup restore BACKUPxxxxxx顺序不能乱尤其是先恢复数据库再启动 GitLab否则 GitLab 启动时发现版本状态和数据库状态不对应会自动尝试迁移很可能会失败。7.2 GitLab 版本升级的正确姿势升级 GitLab 最忌讳的是一步跨太多版本。官方对跨版本升级有严格的路径限制比如从 16.x 升到 17.x有的中间版本可能要求你先升到 16.11。所以升级前一定先查升级路径文档。我的操作流程是# 1. 停掉旧容器 docker compose down # 2. 备份配置文件和数据目录 cp -a /srv/gitlab/config /srv/backups/gitlab-config-$(date %F) docker run --rm -v /srv/gitlab/data:/backup busybox tar czf /backup-gitlab-data.tar.gz /backup # 3. 修改 docker-compose.yml 镜像版本 # 4. 重新拉取并启动 docker compose pull gitlab docker compose up -d升级后第一次启动reconfigure 时间比平时长很多这是正常的数据库迁移也需要时间。等容器状态变healthy后先登录页面看版本号再打开项目仓库确认历史 commit 和 MR 都正常最后跑一次备份。升级后的备份很重要万一有隐藏问题至少能优雅回滚。7.3 资源占用优化关闭不需要的组件GitLab 默认装了一整套生态组件很多单机部署根本用不上。除了前面说的 Prometheus 和 Grafana还有几个可以按需关闭的组件nginx[enable] true # 如果你前面架了其他 Nginx 做反代可以关闭内置 Nginx registry[enable] false # 不打算做容器镜像仓库就关掉 gitlab_workhorse[enable] true # GitLab 核心组件别关 gitaly[enable] true # Git 仓库存储核心别关关闭 Container Registry 能省下一部分内存同时端口 5050 的映射也可以从 Compose 文件里去掉。如果你要用 GitLab CI/CD那 Runner 是额外的东西GitLab 主容器管不到它。热词里有人说gitlab ci/cd中docker镜像构建与自动化部署实践这套环境跑起来之后最顺理成章的扩展就是注册一个 Docker Executor 的 Runner然后写.gitlab-ci.yml用docker build构建镜像再推到 Hub 或者私有仓库。Runner 建议也以容器方式部署和 GitLab 主容器一起放在 Docker 里维护成本很低。我在给团队做落地培训的时候最后留的一句话是这套方案别看步骤多真正执行下来不到半天就能跑通但数据库字符集必须在第一次启动前定好、备份必须坚持做、升级永远先备份这三条红线守住了后面基本就是按时升版本、日常看日志的节奏了。如果你只是自己的小项目用把 Prometheus、Grafana、Registry 全关了2GB 内存的小机器扛一个 GitLab 加 MySQL 也是能跑起来的无非慢一点稳定压倒一切。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门