本文详解如何自建GitLab代码仓库,配置CI/CD自动化流水线,打造完整的团队协作开发环境。
前言
代码托管平台的选择:
- GitHub:开源首选,但私有仓库有限制
- Gitee:国内快,但有审查
- 自建GitLab:完全自主,功能强大
对于企业或有隐私需求的团队,自建GitLab是最好的选择:
- 代码完全在自己手里
- 无限私有仓库
- 内置CI/CD
- 功能比GitHub还全
今天来搭建一套完整的GitLab + CI/CD环境。
一、GitLab部署
1.1 服务器要求
| 配置 | 最低 | 推荐 |
|---|---|---|
| CPU | 2核 | 4核+ |
| 内存 | 4GB | 8GB+ |
| 磁盘 | 50GB | 100GB+ SSD |
注意:GitLab比较吃资源,4GB内存勉强能跑,8GB以上才流畅。
1.2 Docker Compose部署
yaml
# docker-compose.yml
version: '3.8'
services:
gitlab:
image: gitlab/gitlab-ce:latest
container_name: gitlab
restart: always
hostname: 'gitlab.example.com'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://gitlab.example.com'
gitlab_rails['gitlab_shell_ssh_port'] = 2222
# 邮件配置(可选)
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.example.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "gitlab@example.com"
gitlab_rails['smtp_password'] = "password"
gitlab_rails['smtp_domain'] = "example.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['gitlab_email_from'] = 'gitlab@example.com'
ports:
- '80:80'
- '443:443'
- '2222:22'
volumes:
- './gitlab/config:/etc/gitlab'
- './gitlab/logs:/var/log/gitlab'
- './gitlab/data:/var/opt/gitlab'
shm_size: '256m'
bash
# 启动
docker compose up -d
# 等待启动完成(第一次需要几分钟)
docker logs -f gitlab
# 获取初始root密码
docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
1.3 初始配置
1. 访问 http://服务器IP
2. 用户名:root
3. 密码:上一步获取的初始密码
4. 登录后修改密码
建议配置:
- Admin Area → Settings → Sign-up restrictions → 关闭注册
- Admin Area → Settings → Visibility → 设置默认私有
1.4 创建用户和项目
1. Admin Area → Users → New User
2. 创建项目组:Groups → New Group
3. 创建项目:Projects → New Project
4. 添加SSH Key:User Settings → SSH Keys
二、GitLab Runner配置
2.1 Runner是什么
Runner是执行CI/CD任务的执行器,可以部署在:
- GitLab服务器本机
- 单独的服务器(推荐)
- 开发者本地
2.2 安装Runner
bash
# Docker方式安装
docker run -d --name gitlab-runner --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v gitlab-runner-config:/etc/gitlab-runner \
gitlab/gitlab-runner:latest
2.3 注册Runner
bash
# 获取注册Token
# GitLab → Admin Area → Runners → 复制Token
# 注册Runner
docker exec -it gitlab-runner gitlab-runner register
Enter the GitLab instance URL: http://gitlab.example.com
Enter the registration token: [粘贴Token]
Enter a description: my-runner
Enter tags: docker,build
Enter an executor: docker
Enter the default Docker image: docker:latest
2.4 Runner配置优化
bash
# 编辑配置
docker exec -it gitlab-runner nano /etc/gitlab-runner/config.toml
toml
[[runners]]
name = "my-runner"
url = "http://gitlab.example.com"
token = "xxx"
executor = "docker"
[runners.docker]
tls_verify = false
image = "docker:latest"
privileged = true # 允许Docker in Docker
disable_cache = false
volumes = ["/cache", "/var/run/docker.sock:/var/run/docker.sock"]
三、CI/CD流水线配置
3.1 基本概念
yaml
# .gitlab-ci.yml 结构
stages: # 阶段定义
- build
- test
- deploy
variables: # 全局变量
APP_NAME: "my-app"
job_name: # 任务定义
stage: build # 所属阶段
script: # 执行脚本
- echo "Building..."
only: # 触发条件
- main
3.2 Java项目示例
yaml
# .gitlab-ci.yml
stages:
- build
- test
- package
- deploy
variables:
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
cache:
paths:
- .m2/repository/
build:
stage: build
image: maven:3.8-jdk-11
script:
- mvn compile
only:
- main
- develop
test:
stage: test
image: maven:3.8-jdk-11
script:
- mvn test
only:
- main
- develop
package:
stage: package
image: maven:3.8-jdk-11
script:
- mvn package -DskipTests
artifacts:
paths:
- target/*.jar
expire_in: 1 week
only:
- main
deploy:
stage: deploy
image: docker:latest
services:
- docker:dind
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
only:
- main
3.3 Node.js项目示例
yaml
# .gitlab-ci.yml
stages:
- install
- test
- build
- deploy
cache:
paths:
- node_modules/
install:
stage: install
image: node:18
script:
- npm ci
artifacts:
paths:
- node_modules/
expire_in: 1 hour
test:
stage: test
image: node:18
script:
- npm run test
dependencies:
- install
build:
stage: build
image: node:18
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
dependencies:
- install
only:
- main
deploy:
stage: deploy
image: alpine:latest
script:
- apk add rsync openssh-client
- rsync -avz --delete dist/ user@server:/var/www/app/
only:
- main
when: manual # 手动触发
3.4 Docker镜像构建
yaml
# .gitlab-ci.yml
build-image:
stage: package
image: docker:latest
services:
- docker:dind
variables:
DOCKER_TLS_CERTDIR: ""
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker build -t $CI_REGISTRY_IMAGE:latest .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
only:
- main
四、分支策略与代码审查
4.1 Git Flow分支模型
main ──●───────────●───────────●──→ 生产环境
↑ ↑ ↑
release ──●───────────●───────────●──→ 预发布
↑ ↑
develop ──●───●───●───●───●───●───●──→ 开发主线
↑ ↑ ↑
feature ──●───● ●───● ●───●───→ 功能分支
4.2 分支保护
Settings → Repository → Protected Branches
main分支:
- Allowed to merge: Maintainers
- Allowed to push: No one
- Require approval: 1人以上
4.3 Merge Request模板
markdown
<!-- .gitlab/merge_request_templates/default.md -->
## 变更描述
<!-- 描述这个MR做了什么 -->
## 变更类型
- [ ] 新功能
- [ ] Bug修复
- [ ] 重构
- [ ] 文档更新
## 测试说明
<!-- 如何测试这个变更 -->
## Checklist
- [ ] 代码已自测
- [ ] 更新了相关文档
- [ ] 添加了必要的测试
五、团队远程协作
5.1 场景挑战
团队分布:
- 开发A:公司内网
- 开发B:家里远程
- 开发C:出差酒店
- GitLab:公司内网服务器
问题:开发B、C无法访问公司内网的GitLab
5.2 解决方案
方案1:GitLab暴露公网
❌ 风险高,容易被攻击
❌ 需要公网IP和域名
方案2:VPN接入
⚠️ 需要VPN服务器
⚠️ 配置复杂
方案3:组网软件(推荐)
使用组网软件(如星空组网)将团队成员和GitLab服务器组成虚拟局域网:
┌──────────────┐
│ GitLab │
│ 10.10.0.1 │←─┐
└──────────────┘ │
│ 虚拟局域网
┌──────────────┐ │
│ 开发A │←─┤
│ 10.10.0.2 │ │
└──────────────┘ │
│
┌──────────────┐ │
│ 开发B │←─┤
│ 10.10.0.3 │ │
└──────────────┘ │
│
┌──────────────┐ │
│ 开发C │←─┘
│ 10.10.0.4 │
└──────────────┘
配置步骤:
bash
# 1. GitLab服务器安装组网客户端
# 2. 所有开发者电脑安装组网客户端
# 3. 登录同一账号
# 4. 修改git remote地址为组网IP
# 原地址
git remote set-url origin http://192.168.1.100/group/project.git
# 改为组网IP
git remote set-url origin http://10.10.0.1/group/project.git
效果:
- 任何地点都能访问GitLab
- 不需要公网暴露
- 加密传输,安全
- 配置简单,一次设置
5.3 SSH配置
bash
# ~/.ssh/config
Host gitlab
HostName 10.10.0.1 # 组网IP
Port 2222
User git
IdentityFile ~/.ssh/gitlab_key
bash
# 克隆使用
git clone gitlab:group/project.git
六、备份与恢复
6.1 备份配置
bash
# 手动备份
docker exec -t gitlab gitlab-backup create
# 备份文件位置
./gitlab/data/backups/
# 定时备份(crontab)
0 3 * * * docker exec -t gitlab gitlab-backup create CRON=1
6.2 恢复
bash
# 停止相关服务
docker exec -it gitlab gitlab-ctl stop puma
docker exec -it gitlab gitlab-ctl stop sidekiq
# 恢复备份(BACKUP为备份时间戳)
docker exec -it gitlab gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce
# 重启
docker restart gitlab
6.3 异地备份
bash
# 备份到远程服务器(通过组网)
rsync -avz ./gitlab/data/backups/ user@10.10.0.5:/backup/gitlab/
七、常见问题
7.1 内存不足
bash
# 减少Sidekiq并发
gitlab_rails['sidekiq_concurrency'] = 5
# 减少Puma workers
puma['worker_processes'] = 2
# 禁用Prometheus(省内存)
prometheus_monitoring['enable'] = false
7.2 克隆速度慢
bash
# 启用Git LFS存储大文件
git lfs install
git lfs track "*.psd"
git lfs track "*.zip"
7.3 502错误
bash
# 通常是启动未完成或内存不足
# 查看日志
docker logs gitlab
# 重启
docker restart gitlab
八、总结
GitLab + CI/CD搭建要点:
- 服务器配置:至少8GB内存
- Docker部署:最简单的部署方式
- Runner配置:单独部署,避免资源竞争
- CI/CD流水线:按项目类型配置
- 分支保护:main分支必须通过MR
- 远程协作:组网软件打通网络
- 定期备份:数据无价
我的团队配置:
- GitLab服务器:公司内网,8GB内存
- Runner:单独一台4GB服务器
- 远程访问:星空组网
- 备份:每天自动备份,rsync到另一台机器
自建GitLab虽然需要维护,但完全掌控数据的感觉真的很好。
参考资料
- GitLab官方文档:https://docs.gitlab.com/
- GitLab CI/CD文档:https://docs.gitlab.com/ee/ci/
- GitLab Docker安装:https://docs.gitlab.com/ee/install/docker.html
💡 建议:先在测试服务器上搭建,熟悉流程后再部署到生产环境。数据迁移GitLab有完善的备份恢复机制。