跳转至

GitLab

安装部署

Debian安装GitLab

# 更新、安装必要软件
sudo apt update
sudo apt upgrade
sudo apt install -y curl openssh-server ca-certificates tzdata perl
# 下载安装GitLab CE
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
sudo EXTERNAL_URL="http://127.0.0.1:8081" apt install gitlab-ce
# 配置GitLab
gitlab-ctl reconfigure
#停止服务
sudo gitlab-ctl stop 
# 启动服务
sudo gitlab-ctl reconfigure
# 重启所有gitlab组件
sudo gitlab-ctl restart
# 启动所有gitlab组件
sudo gitlab-ctl start

默认登录和初始化密码,查看/etc/gitlab/initial_root_password

卸载

sudo gitlab-ctl stop 
apt-get purge gitlab-ce
apt-get autoremove

配置

优化使用

nano /etc/gitlab/gitlab.rb

external_url 'https://gitlab.lyricn.com'

nginx['listen_port'] = 8081
nginx['listen_https'] = false

# 推荐设置为:CPU核数 - 1,或者更保守设为 2
puma['worker_processes'] = 2
# 默认是总内存的 25%,可根据实际情况固定大小
postgresql['shared_buffers'] = "1GB"

# 关闭不必要的组件
# 不需要监控全家桶(Prometheus, Grafana 等),关掉它们可以节省大量内存(约 1-2GB)
prometheus['enable'] = false
grafana['enable'] = false

# 保留最近 7 天的日志
logging['logrotate_frequency'] = "daily"
logging['logrotate_rotate'] = 7
# 限制单个日志文件大小
logging['logrotate_size'] = "100M"
# 开启压缩
logging['logrotate_compress'] = "compress"

执行以下命令生效:

sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart

使用外部Nginx

nginx['enable'] = false
gitlab_workhorse['listen_network'] = "tcp"
gitlab_workhorse['listen_addr'] = "127.0.0.1:8081"
external_url 'https://gitlab.xxx.com'
gitlab_rails['trusted_proxies'] = ['gitlab.xxx.com']

nginx['enable'] = false 禁用自带nginx gitlab_workhorse['listen_network'] = "tcp" 允许gitlab-workhorse监听TCP gitlab_workhorse['listen_addr'] = "127.0.0.1:8081" 设置gitlab端口为8081 注意8081未占用 或者可以不使用tcp,改成unix,unix://var/opt/gitlab/gitlab-rails/sockets/gitlab.socket external_url 'https://gitlab.xxx.com' 设置git访问: 域名:nginx端口 此处80为独立nginx端口 gitlab_rails['trusted_proxies'] = ['gitlab.xxx.com'] 设置gitlab域名

nginx配置参考:

upstream gitlab {
  server unix://var/opt/gitlab/gitlab-rails/sockets/gitlab.socket;
}

location / {
    proxy_redirect off;
    proxy_pass http://gitlab;
    proxy_set_header  Host                $http_host;
    proxy_set_header  X-Real-IP           $remote_addr;
    proxy_set_header  REMOTE-HOST         $remote_addr;
    proxy_set_header  X-Forwarded-Ssl     on;
    proxy_set_header  X-Forwarded-For     $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto   $scheme;
    proxy_set_header  X-Frame-Options     SAMEORIGIN;
    client_max_body_size        100m;
    client_body_buffer_size     128k;
    proxy_buffer_size           4k;
    proxy_buffers               4 32k;
    proxy_busy_buffers_size     64k;
    proxy_temp_file_write_size  64k;
}

刷新配置并重启:gitlab-ctl reconfigure && gitlab-ctl restart

备份数据

脚本主要完成三件事:

  1. 备份配置文件:将 /etc/gitlab/ 打包,这包含了解密数据库所需的密钥。
  2. 备份应用数据:使用 GitLab 自带工具备份代码库、数据库等。
  3. 清理旧备份:保留最近 7 天的备份,自动删除过期的。

备份脚本 (gitlab_backup.sh) 将此内容保存为 /opt/gitlab_backup.sh 或其他你喜欢的位置。

#!/bin/bash

# ================= 配置区域 =================
# 备份保存目录
BACKUP_DIR="/var/opt/gitlab/backups"
# 配置文件备份目录 (会自动创建)
CONFIG_BACKUP_DIR="${BACKUP_DIR}/config_backups"
# 保留最近多少天的备份
KEEP_DAYS=7
# 日志文件
LOG_FILE="/var/log/gitlab_backup.log"

# 获取当前日期,用于文件名
DATE=$(date "+%Y%m%d_%H%M%S")

# ================= 函数定义 =================
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 检查是否以 root 运行
if [ "$EUID" -ne 0 ]; then
  log "错误: 请使用 root 权限运行此脚本"
  exit 1
fi

# 创建目录
mkdir -p "$CONFIG_BACKUP_DIR"

log "=== 开始 GitLab 备份任务 ==="

# -------------------------------------------
# 1. 备份配置文件 (/etc/gitlab)
# -------------------------------------------
log "正在备份配置文件..."
# GitLab 提供了专门的命令 backup-etc,它会自动打包 /etc/gitlab 并保存到 /etc/gitlab/config_backup/
# 我们手动执行打包以便统一管理存储位置
tar -czf "${CONFIG_BACKUP_DIR}/gitlab_config_${DATE}.tar.gz" -C /etc/gitlab .
if [ $? -eq 0 ]; then
    log "配置文件备份成功: ${CONFIG_BACKUP_DIR}/gitlab_config_${DATE}.tar.gz"
else
    log "错误: 配置文件备份失败!"
    # 配置文件备份失败不应中断数据备份,继续执行
fi

# -------------------------------------------
# 2. 备份 GitLab 应用数据 (Repositories, DB, etc.)
# -------------------------------------------
log "正在备份 GitLab 应用数据..."
# SKIP=tar,lfs 可以跳过部分数据以加快速度,但建议完整备份
# CRON=1 选项可以抑制非必要的输出,适合定时任务
/opt/gitlab/bin/gitlab-backup create CRON=1
if [ $? -eq 0 ]; then
    log "GitLab 应用数据备份命令执行成功"
else
    log "严重错误: GitLab 应用数据备份失败!"
    exit 1
fi

# -------------------------------------------
# 3. 清理过期备份
# -------------------------------------------
log "正在清理 ${KEEP_DAYS} 天前的旧备份..."

# 清理配置文件备份
find "$CONFIG_BACKUP_DIR" -type f -name "gitlab_config_*.tar.gz" -mtime +$KEEP_DAYS -delete
# 清理 GitLab 标准数据备份 (GitLab 自带配置 gitlab_rails['backup_keep_time'] 也能管理这个,但这里双重保险)
find "$BACKUP_DIR" -maxdepth 1 -type f -name "*_gitlab_backup.tar" -mtime +$KEEP_DAYS -delete

log "清理完成"
log "=== 备份任务结束 ==="

数据恢复

脚本

脚本将执行以下关键步骤: 1. 自动识别:找到备份目录中“最新”的配置文件和数据文件。 2. 恢复配置:先解压配置文件到 /etc/gitlab/,确保加密密钥 (gitlab-secrets.json) 就位。 3. 重载配置:运行 gitlab-ctl reconfigure 让 GitLab 识别新配置。 4. 准备服务:停止 Puma 和 Sidekiq(必须停止这些连接数据库的服务才能恢复),但保持数据库运行。 5. 恢复数据:执行 GitLab 标准恢复流程。

收尾:重启服务并检查健康状态。 恢复脚本 (gitlab_restore.sh) 请将此内容保存为 /opt/gitlab_restore.sh

#!/bin/bash

# ================= 配置区域 =================
# 备份所在目录 (必须与备份脚本中的位置一致)
BACKUP_DIR="/var/opt/gitlab/backups"
CONFIG_BACKUP_DIR="${BACKUP_DIR}/config_backups"

# 日志文件
LOG_FILE="/var/log/gitlab_restore.log"

# ================= 函数定义 =================
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

confirm() {
    read -r -p "$1 [y/N] " response
    case "$response" in
        [yY][eE][sS]|[yY]) 
            true
            ;;
        *)
            false
            ;;
    esac
}

# 检查 root 权限
if [ "$EUID" -ne 0 ]; then
  log "错误: 必须使用 root 权限运行此脚本"
  exit 1
fi

log "=== 开始 GitLab 恢复流程 ==="

# -------------------------------------------
# 1. 查找最新的备份文件
# -------------------------------------------
# 查找最新的配置文件备份 (*.tar.gz)
LATEST_CONFIG=$(ls -t "${CONFIG_BACKUP_DIR}"/gitlab_config_*.tar.gz 2>/dev/null | head -n 1)

# 查找最新的数据备份 (*_gitlab_backup.tar)
LATEST_DATA=$(ls -t "${BACKUP_DIR}"/*_gitlab_backup.tar 2>/dev/null | head -n 1)

if [ -z "$LATEST_CONFIG" ] || [ -z "$LATEST_DATA" ]; then
    log "错误: 未找到备份文件!"
    log "请检查目录: $BACKUP_DIR$CONFIG_BACKUP_DIR"
    exit 1
fi

log "发现最新配置文件: $(basename "$LATEST_CONFIG")"
log "发现最新数据文件: $(basename "$LATEST_DATA")"

if ! confirm "警告: 即将覆盖当前 GitLab 数据和配置,确认继续吗?"; then
    log "用户取消操作"
    exit 0
fi

# -------------------------------------------
# 2. 恢复配置文件 (/etc/gitlab)
# -------------------------------------------
log "步骤 1/5: 正在恢复配置文件..."

# 备份当前的 gitlab.rb 以防万一 (如果新机器是刚装好的,这步是防御性的)
if [ -f "/etc/gitlab/gitlab.rb" ]; then
    cp /etc/gitlab/gitlab.rb /etc/gitlab/gitlab.rb.pre_restore
fi

# 解压配置覆盖到 /etc/gitlab
# -C 指定解压目标目录
# --overwrite 强制覆盖
tar -xzf "$LATEST_CONFIG" -C /etc/gitlab/ --overwrite

if [ $? -eq 0 ]; then
    log "配置文件解压成功"
else
    log "错误: 配置文件解压失败"
    exit 1
fi

# 修复权限 (至关重要,特别是 gitlab-secrets.json)
log "正在修复配置文件权限..."
chmod 600 /etc/gitlab/gitlab-secrets.json
chown root:root /etc/gitlab/gitlab-secrets.json

# -------------------------------------------
# 3. 首次重载配置
# -------------------------------------------
log "步骤 2/5: 应用新配置 (Reconfigure)..."
# 这一步是为了让 GitLab 识别新的 gitlab.rb 设置,并确保数据库连接正常
gitlab-ctl reconfigure

if [ $? -ne 0 ]; then
    log "错误: gitlab-ctl reconfigure 失败,请检查配置文件"
    exit 1
fi

# -------------------------------------------
# 4. 停止相关服务准备恢复
# -------------------------------------------
log "步骤 3/5: 停止 Puma 和 Sidekiq 服务..."
# 恢复数据库时,必须停止连接数据库的应用服务
gitlab-ctl stop puma
gitlab-ctl stop sidekiq

# 确认服务状态
gitlab-ctl status | grep "down: puma" > /dev/null
PUMA_STATUS=$?
gitlab-ctl status | grep "down: sidekiq" > /dev/null
SIDEKIQ_STATUS=$?

if [ $PUMA_STATUS -eq 0 ] && [ $SIDEKIQ_STATUS -eq 0 ]; then
    log "服务已停止,数据库 (PostgreSQL) 保持运行"
else
    log "警告: 服务停止可能不彻底,尝试强制停止..."
    gitlab-ctl stop puma
    gitlab-ctl stop sidekiq
fi

# -------------------------------------------
# 5. 执行数据恢复
# -------------------------------------------
# 提取时间戳 ID (例如从 170496_...tar 提取 170496_...)
# GitLab restore 命令只需要 "_gitlab_backup.tar" 之前的部分
BACKUP_TIMESTAMP=$(basename "$LATEST_DATA" | sed 's/_gitlab_backup.tar//')

log "步骤 4/5: 开始恢复数据 (ID: $BACKUP_TIMESTAMP)..."
log "这可能需要几分钟到几小时,取决于数据量..."

# force=yes 自动回答所有 "yes" 确认,避免脚本暂停
gitlab-backup restore BACKUP="$BACKUP_TIMESTAMP" force=yes

if [ $? -eq 0 ]; then
    log "数据恢复命令执行成功!"
else
    log "严重错误: 数据恢复失败!请查看上方错误输出。"
    exit 1
fi

# -------------------------------------------
# 6. 收尾与重启
# -------------------------------------------
log "步骤 5/5: 重启服务并检查..."

# 再次 reconfigure 确保一切同步
gitlab-ctl reconfigure
# 重启所有服务
gitlab-ctl restart

log "正在等待服务启动..."
sleep 30 # 给一点启动时间

log "运行系统健康检查..."
gitlab-rake gitlab:check SANITIZE=true

log "=== 恢复流程结束 ==="
log "请访问 Web 界面验证数据。"