Post

gitlab 오토백업 설정

목차


개요

본 문서는 GitLab 설치 시 사용했던 docker-compose 내용을 바탕으로 진행함.

GitLab 설치


방법

우선 gitlab을 동작시키고 있다면 docker-compose down 명령어로 컨테이너를 종료시킨다.

(docker-compose.yml에 백업 설정을 추가로 해줘야 하기 때문)

아래 3라인을 추가한다.

1
2
3
# gitlab backup파일 저장 시간 2592000sec -> 30days
gitlab_rails['backup_keep_time'] = 2592000
gitlab_rails['backup_path'] = '/usr/local/backup'

변경된 docker-compose.yml 파일은 아래와 같다.

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
version: '3.9'

services:
  gitlab:
    image: "gitlab/gitlab-ce:latest"
    container_name: 'container_name'
    restart: always
    hostname: "gitlab.iasdf.com" # hostname
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.iasdf.com' # 외부 ip 혹은 접근할 ip
        # gitlab ssh port
        gitlab_rails['gitlab_shell_ssh_port'] = 22
        # gitlab backup파일 저장 시간 2592000sec -> 30days
        gitlab_rails['backup_keep_time'] = 2592000
        gitlab_rails['backup_path'] = '/usr/local/backup'
        # Add any other gitlab.rb configuration here, each on its own line
      TZ: 'Asia/Seoul'
    ports:
      - "80:80"   # http 접근포트
      - "443:443" # https 접근포트
      - "22:22" # ssh 접근포트
    volumes:
      - "/gitlab/config:/etc/gitlab"
      - "/gitlab/logs:/var/log/gitlab"
      - "/gitlab/data:/var/opt/gitlab"
      - "/mnt/gitlab_backup:/usr/local/backup"

docker-compose up -d 명령어를 통해 깃랩 컨테이너를 다시 실행시킨다.

gitlab 컨테이너 내부에서 gitlab-backup create 명령어를 통해 백업을 진행할 수 있다.

1
2
3
4
docker exec -it <container_name> bash
gitlab-backup create

# docker exec -t <container_name> gitlab-backup create 도 가능.

docker-compose.yml에서 설정한 backup_path 경로에 (timestamp 값)_(gitlab 버전)_gitlab_backup.tar 파일이 생성된다.

필자는 컨테이너의 backup_path를 호스트의 /mnt/gitlab_backup 으로

매주 토요일 새벽 1시마다 백업을 진행할 수 있도록 크론에 등록한다.

크론에 등록하기 위해 gitlab_backup.sh 파일을 생성하여 내용을 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash

CONTAINER_NAME=container_name

BACKUP_DIR=/backup_directory

BACKUP_LOG_PATH=$BACKUP_DIR/backup_log
BACKUP_CREATE_LOG_NAME=backup_create.log

# if use CRON=1 don't leave a backup log
# docker exec -t $CONTAINER_NAME gitlab-backup create CRON=1
date >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
docker exec -t $CONTAINER_NAME gitlab-backup create >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME

내용 추가 후 저장하고 나와 chmod 755 ./gitlab_backup.sh 로 파일에 실행 권한을 추가한다.

gitlab-backup create 명령어 만으로는 gitlab.rb 등의 config 파일은 백업이 되지 않으므로 추가로 백업을 진행해야 한다.

깃랩 config 설정의 경우 docker-compose.yml 에서 config 설정 볼륨을 /gitlab/config 로 진행하였기에 해당 설정파일을 압축하여 따로 보관할 수 있도록 한다.

gitlab_backup.sh 백업 스크립트에 내용을 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GITLAB_DIR=/gitlab_bind_mount_path

# 깃랩 마운트 위치로 이동하여 압축 진행
cd $GITLAB_DIR
MONTH=`date | awk -F ' ' '{ print $2 }'`
DAY=`date | awk -F ' ' '{ print $3 }'`
COMPRESS_NAME=${MONTH}_${DAY}_config_backup.tgz
echo "gitlab config file backup" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
tar -zcf ${COMPRESS_NAME} ./config/
echo "compress success [ ${COMPRESS_NAME} ]" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
mv ${COMPRESS_NAME} ${BACKUP_DIR}
echo "compress file move success"
ls -alhF ${BACKUP_DIR}/${COMPRESS_NAME} >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME

echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
cd -

30일이 지난 백업 파일의 경우 자동으로 삭제하는 기능을 추가한다.

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
BACKUP_LIFETIME=30
BACKUP_OLDER_DELETE_NAME=older_remove.log

# Find and delete backup tar files older than 30 days
# find $BACKUP_DIR -name "*_gitlab_backup.tar" -mtime +$BACKUP_LIFETIME -type f -exec rm -f {} \;

# data/source 백업파일을 BACKUP_LIFETIME 일이 지나면 제거하는 스크립트
find_backup_dir=`find $BACKUP_DIR -name "*_gitlab_backup.tar" -mtime +$BACKUP_LIFETIME -type f`

if [ "$find_backup_dir" == "" ]; then
	date >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "cannot find remove data backup file" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
else
	date >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "remove_file (data)" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "$find_dir" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME

	rm -rf $find_dir
fi
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME

# config 백업파일을 BACKUP_LIFETIME 일이 지나면 제거하는 스크립트
find_config_dir=`find $BACKUP_DIR -name "*_config_backup.tgz" -mtime +$BACKUP_LIFETIME -type f`

if [ "$find_config_dir" == "" ]; then
	date >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "cannot find remove config backup file" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
else
	date >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "remove_file (config)" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "$find_dir" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME

	rm -rf $find_dir
fi
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME

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
#!/bin/bash

CONTAINER_NAME=container_name

BACKUP_LIFETIME=30
BACKUP_DIR=/backup_directory
GITLAB_DIR=/gitlab_bind_mount_path

BACKUP_LOG_PATH=$BACKUP_DIR/backup_log
BACKUP_CREATE_LOG_NAME=backup_create.log
BACKUP_OLDER_DELETE_NAME=older_remove.log

# if use CRON=1 don't leave a backup log
# docker exec -t $CONTAINER_NAME gitlab-backup create CRON=1
date >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
docker exec -t $CONTAINER_NAME gitlab-backup create >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME

# 깃랩 마운트 위치로 이동하여 압축 진행
cd $GITLAB_DIR
MONTH=`date | awk -F ' ' '{ print $2 }'`
DAY=`date | awk -F ' ' '{ print $3 }'`
COMPRESS_NAME=${MONTH}_${DAY}_config_backup.tgz
echo "gitlab config file backup" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
tar -zcf ${COMPRESS_NAME} ./config/
echo "compress success [ ${COMPRESS_NAME} ]" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
mv ${COMPRESS_NAME} ${BACKUP_DIR}
echo "compress file move success"
ls -alhF ${BACKUP_DIR}/${COMPRESS_NAME} >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME

echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_CREATE_LOG_NAME
cd -

# Find and delete backup tar files older than 30 days
# find $BACKUP_DIR -name "*_gitlab_backup.tar" -mtime +$BACKUP_LIFETIME -type f -exec rm -f {} \;

# data/source 백업파일을 BACKUP_LIFETIME 일이 지나면 제거하는 스크립트
find_backup_dir=`find $BACKUP_DIR -name "*_gitlab_backup.tar" -mtime +$BACKUP_LIFETIME -type f`

if [ "$find_backup_dir" == "" ]; then
	date >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "cannot find remove data backup file" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
else
	date >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "remove_file (data)" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "$find_dir" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME

	rm -rf $find_dir
fi
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME

# config 백업파일을 BACKUP_LIFETIME 일이 지나면 제거하는 스크립트
find_config_dir=`find $BACKUP_DIR -name "*_config_backup.tgz" -mtime +$BACKUP_LIFETIME -type f`

if [ "$find_config_dir" == "" ]; then
	date >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "cannot find remove config backup file" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
else
	date >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "remove_file (config)" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
	echo "$find_dir" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME

	rm -rf $find_dir
fi
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME
echo "" >> $BACKUP_LOG_PATH/$BACKUP_OLDER_DELETE_NAME

해당 스크립트를 cron으로 매주 토요일 새벽 1시에 동작하도록 구성한다.

/etc/crontab 파일을 열어 다음과 같이 내용을 추가하자

1
2
3
# Gitlab container data backup
# in Sat 1 am
00 01 * * 6 root /<path>/gitlab_backup.sh

이후 백업 스크립트 로그를 rotate시키기 위해 logrotate 설정을 진행해준다.

This post is licensed under CC BY 4.0 by the author.