docker gitlab容器数据备份步骤
自动备份
创建
/home/scripts
下命名为gitlab_backup.sh
的脚本1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 启用严格错误检查
set -euo pipefail
# 配置参数(允许通过环境变量覆盖)
BACKUP_ROOT=${BACKUP_ROOT:-"${HOME}/gitlab-docker/backup"}
CONTAINER_NAME=${CONTAINER_NAME:-"gitlab"}
RETAIN_DAYS=${RETAIN_DAYS:-28}
# 生成日期标签
DATE=$(date +%Y%m%d_%H%M)
BACKUP_DIR="${BACKUP_ROOT}/backup_${DATE}"
LOG_FILE="${BACKUP_ROOT}/backup_log.txt"
# 创建备份目录(logs不做备份,这里为挂载新容器做准备)
mkdir -p "${BACKUP_DIR}/gitlab/"{config,logs,data}
# 捕获错误并输出信息函数
handle_error() {
echo "" >> "$LOG_FILE"
echo "${DATE}" >> "$LOG_FILE"
echo "Backup completed Failed! ! !" >> "$LOG_FILE"
echo "Error: $1" >> "$LOG_FILE"
echo "Error: $1" | mail -s "gitlab-backup" user@qq.com
# 如果备份失败,删除创建的文件夹
sudo rm -rf "${BACKUP_DIR}"
exit 1
}
# 1. GitLab 应用数据备份
echo "Step 1: Creating GitLab application backup..."
if ! docker exec -t "$CONTAINER_NAME" gitlab-rake gitlab:backup:create; then
handle_error "Failed to create GitLab application backup."
fi
# 2. 备份配置文件
CONFIG_SRC="${HOME}/gitlab-docker/gitlab/config"
echo "Step 2: Backing up configuration..."
if ! sudo tar -czf "${BACKUP_DIR}/gitlab/config/gitlab_config_${DATE}.tar.gz" -C "$CONFIG_SRC" .; then
handle_error "Failed to backup GitLab configuration."
fi
# 3. 移动 GitLab 自动生成的备份文件
DOCKER_BACKUP_SRC="${HOME}/gitlab-docker/gitlab/data/backups"
if [ ! -d "$DOCKER_BACKUP_SRC" ] || [ -z "$(sudo ls -A $DOCKER_BACKUP_SRC)" ]; then
handle_error "Backup source directory '$DOCKER_BACKUP_SRC' is empty or does not exist."
fi
echo "Step 3: Locating latest backup file..."
LATEST_BACKUP=$(sudo find "$DOCKER_BACKUP_SRC" -type f -name '*.tar' -printf '%T@ %p\n' | sort -n | tail -1 | cut -d' ' -f2-)
if [ -z "$LATEST_BACKUP" ]; then
handle_error "No backup file found in $DOCKER_BACKUP_SRC"
fi
echo "Found latest backup: $LATEST_BACKUP"
if ! sudo mv -v "$LATEST_BACKUP" "${BACKUP_DIR}/gitlab/data"; then
handle_error "Failed to copy the latest backup file."
fi
# 4. 清理旧备份
echo "Step 4: Cleaning up old backups..."
if ! sudo find "$BACKUP_ROOT" -name 'backup_*' -mtime +"$RETAIN_DAYS" -print -exec rm -rf {} +; then
handle_error "Failed to clean up old backups"
fi
# 5. 压缩整个备份目录
echo "Step 5: Compressing backup directory..."
if ! sudo tar -czf "${BACKUP_ROOT}/backup_${DATE}.tar.gz" -C "${BACKUP_ROOT}" "backup_${DATE}"; then
handle_error "Failed to compress the backup directory."
fi
if ! sudo rm -rf "${BACKUP_DIR}"; then
handle_error "Failed to remove the uncompressed backup directory."
fi
# 6. 记录日志并输出成功信息
echo "" >> "$LOG_FILE"
echo "${DATE}" >> "$LOG_FILE"
echo "Backup completed successfully!" >> "$LOG_FILE"
echo "Compressed backup location: ${BACKUP_ROOT}/backup_${DATE}.tar.gz" >> "$LOG_FILE"
# 输出到shell,方便调试
echo "Backup completed successfully!"
echo "Backup completed successfully!" | mail -s "gitlab-backup" user@qq.com配置邮件服务(将备份结果以网易邮件形式通知到管理员)
安装postfix
1
2sudo apt update
sudo apt install postfix安装过程中选择 Internet Site
编辑配置文件
1
sudo nano /etc/postfix/main.cf
修改/添加以下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# 基本配置
myhostname = localhost
myorigin = /etc/mailname
inet_interfaces = loopback-only
relayhost = [smtp.163.com]:465
# SASL 认证
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = login
# TLS/SSL 加密
smtp_use_tls = yes
smtp_tls_wrappermode = yes
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt配置SMTP认证信息
1
sudo nano /etc/postfix/sasl_passwd
写入以下内容
1
[smtp.163.com]:465 user@163.com:你的授权码
设置发件人域名
1
sudo nano /etc/mailname
写入以下内容
1
163.com
生成数据库文件并设置权限:
1
2sudo postmap /etc/postfix/sasl_passwd
sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db重启Postfix
1
sudo systemctl restart postfix
测试发送邮件
1
echo "test" | mail -s "test subject" user@qq.com
可能存在的问题
MAIL FROM配置不正确,需要强制修改
修改postfix配置文件
1
sudo nano /etc/postfix/main.cf
添加以下内容
1
smtp_generic_maps = hash:/etc/postfix/generic
创建地址映射文件
1
sudo nano /etc/postfix/generic
写入以下内容
1
2
3
4@logo-ubuntu-fd user@163.com
@localhost user@163.com
# 动态匹配当前主机名
@$(myhostname) user@163.com生成映射数据库
1
sudo postmap /etc/postfix/generic
重启Postfix
1
sudo systemctl restart postfix
自动运行脚本
1
2
3
4
5# 添加权限
chomd +x backup_gitlab.sh
# 通过contab设置定期任务 每周一早上8点执行一次备份
0 8 * * 1 /home/Username/scripts/gitlab_backup.sh为脚本添加sudo免密码权限
1
2
3
4
5# 1.visudo 命令
sudo visudo
# 在文件末尾添加
your-username ALL=(ALL) NOPASSWD: ALL手动触发脚本执行测试
1
./home/Username/scripts/gitlab_backup.sh
说明
- 备份产生的目录结构为gitlab /(config + logs + data),其中logs是一个空文件夹,此举只是为了方便生成新容器时方便挂载,data包含一个gitlab内置备份功能生成的一个tar文件,config则是从源容器完全移植过来的。
- backup下会自动生成一个log.txt文件记录备份结果日志。
恢复
生成一个新的容器(挂载到备份目录上)
1
2
3
4
5
6
7
8
9
10
11
12docker run -d \
--name gitlab-new \
--hostname gitlab.example.com \
--publish 9080:80 \
--publish 9443:443 \
--publish 3222:22 \
--volume $PWD/gitlab/config:/etc/gitlab \
--volume $PWD/gitlab/logs:/var/log/gitlab \
--volume $PWD/gitlab/data:/var/opt/gitlab \
--shm-size 256m \
--restart always \
my-gitlab:16.10.2移动备份文件到新的容器备份文件目录下
1
2
3
4# 进入容器终端
docker exec -it gitlab-new /bin/bash
mv /var/opt/gitlab/1638293100_gitlab_backup.tar /var/opt/gitlab/backups/设置文件权限
1
chown git:git /var/opt/gitlab/backups/1638293100_gitlab_backup.tar
解决PostgreSQL数据库扩展权限问题
修改PostgreSQL相关配置
1
2
3
4
5
6
7vi /var/opt/gitlab/postgresql/data/postgresql.conf
# listen_addresses = ''修改为listen_addresses = '*'
vi /var/opt/gitlab/postgresql/data/pg_hba.conf
# 最下面添加
# local all all trust
# host all all 127.0.0.1/32 trust重启gitlab服务
1
gitlab-ctl restart
修改gitlab账号为超级用户
1
2
3
4
5
6
7gitlab-psql -d gitlabhq_production
gitlabhq_production=# ALTER USER gitlab WITH SUPERUSER;
gitlabhq_production=# ALTER ROLE
gitlabhq_production=# \q
exit
执行恢复
1
2
3
4
5
6
7
8# 停止连接到数据库的进程(在容器内执行)
gitlab-ctl stop puma
gitlab-ctl stop sidekiq
# 执行恢复(替换文件名中的备份时间戳)
gitlab-rake gitlab:backup:restore BACKUP=1638293100
# 按照提示输入 "yes" 确认重启gitlab服务
1
gitlab-ctl restart
检查gitlab数据是否完全恢复
可能遇到的问题 新容器不能正常启动 502代码:修复权限
1
docker exec -it gitlab-new update-permissions