Dockerで立ち上げたGitLabの定期バックアップ方法

## はじめに
どうも！生産技術部のエンジニアです。GitLabのサーバを立ち上げて、最初に実施する事の一つがデータのバックアップだと思います。ここでは、GitLabのアプリケーションデータ及び設定ファイルを定期バックアップする方法を紹介します。

GitLabサーバを一から構築される方は、以下からご覧ください。
[「proxy環境下でDocker Composeを用いてCentOS7上にGitLab Dockerを作成」](https://qiita.com/TomoyukiSugiyama/items/ba7ef0ebab8242dbacb0)

## 環境
* CentOS : 7.6.1810
* Docker-CE : 19.03.1
* Docker Compose : 1.25.0
* GitLab-CE Docker : 12.2.0-ce.0

## 前提条件
Docker、GitLabの導入が実施済みであること。

[「proxy環境下でDocker Composeを用いてCentOS7上にGitLab Dockerを作成」](https://qiita.com/TomoyukiSugiyama/items/ba7ef0ebab8242dbacb0)
を参考に導入してください。
## DockerでGitLabを起動した場合のバックアップ
GitLabのバックアップをする上で、以下の二種類のデータのバックアップが必要になります。

* アプリケーションデータ
 - データベースやリポジトリのデータ
* 設定ファイル
 - `gitlab.rb`や`gitlab-secrets.json`などの設定ファイル

GitLabにはアプリケーションデータ用のバックアップコマンドが用意されていますが、設定ファイルはバックアップされません。公式によると、データベースには二段階認証のための暗号化情報などが含まれますが、それらの情報とそのキーを同じ場所に置くことは、暗号化を行う目的に反しているとか謎、、、細かいことは抜きにして、まずはアプリケーションデータのバックアップ方法から説明します。Dockerでのバックアップ方法は、以下の様に実施します。

```shell:
$ sudo docker exec -t <container name> gitlab-backup create
```

`<container name>`は、以下のコマンドで確認します。

```shell:
$ sudo docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS                PORTS                                                                                    NAMES
dc2c32a5a3d6        gitlab/gitlab-ce:latest       "/assets/wrapper"        8 days ago          Up 8 days (healthy)   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:8001->8001/tcp, 0.0.0.0:4022->22/tcp   gitlab_gitlab_1
```
実際に実行すると、この様なログが表示され、バックアップが出来上がります。

```shell:
$ sudo docker exec -t gitlab_gitlab_1 gitlab-backup create
<略>
2019-12-03 08:22:14 +0000 -- done
2019-12-03 08:22:14 +0000 -- Dumping uploads ... 
2019-12-03 08:22:14 +0000 -- done
2019-12-03 08:22:14 +0000 -- Dumping builds ... 
2019-12-03 08:22:14 +0000 -- done
2019-12-03 08:22:14 +0000 -- Dumping artifacts ... 
2019-12-03 08:22:14 +0000 -- done
2019-12-03 08:22:14 +0000 -- Dumping pages ... 
2019-12-03 08:22:14 +0000 -- done
2019-12-03 08:22:14 +0000 -- Dumping lfs objects ... 
2019-12-03 08:22:14 +0000 -- done
2019-12-03 08:22:14 +0000 -- Dumping container registry images ... 
2019-12-03 08:22:14 +0000 -- [DISABLED]
Creating backup archive: 1575361334_2019_12_03_12.3.5_gitlab_backup.tar ... done
Uploading backup archive to remote storage  ... skipped
Deleting tmp directories ... done
done
done
done
done
done
done
done
Deleting old backups ... done. (0 removed)
Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data 
and are not included in this backup. You will need these files to restore a backup.
Please back them up manually.
Backup task is done.
```
バックアップを確認するとこの様なアーカイブファイルが生成されます。

```shell:
# ls -la /srv/gitlab/data/backups/
total 18344
drwx------.  2 libstoragemgmt root       4096 Dec  3 17:22 .
drwxr-xr-x. 22 root           root       4096 Nov 25 10:11 ..
-rw-r--r--.  1 libstoragemgmt polkitd 2385920 Dec  3 17:22 1575361334_2019_12_03_12.3.5_gitlab_backup.tar
```
## アプリケーションデータの定期バックアップ
設定ファイルには`backup_path`(バックアップファイルの保存先)、`backup_archive_permissions`(ファイルパーミッション)、`backup_keep_time`(キープタイム)を設定します。キープタイムを設定することで、古くなったファイルを自動的に削除してくれます。値の単位は秒ですので、１週間分残したい場合は$７(日間)\times24(時間)\times3600(秒) = 604800$となります。


```ruby:gitlab.rb
### Backup Settings
###! Docs: https://docs.gitlab.com/omnibus/settings/backups.html

gitlab_rails['manage_backup_path'] = true
gitlab_rails['backup_path'] = "/var/opt/gitlab/backups"

###! Docs: https://docs.gitlab.com/ce/raketasks/backup_restore.html#backup-archive-permissions
gitlab_rails['backup_archive_permissions'] = 0644

# gitlab_rails['backup_pg_schema'] = 'public'

###! The duration in seconds to keep backups before they are allowed to be deleted
gitlab_rails['backup_keep_time'] = 604800
```

crontabは定期スケジューリング用のコマンドです。管理者権限を持ったユーザで実施します。

```shell:
$ sudo su -
$ crontab -e
```
上記コマンドを実行すると、エディタが起動しますので、実行したいコマンドを記述し保存します。

```vim:
# 分 時 日 月 曜日 <実行コマンド>
0 2 * * * docker exec -t gitlab_gitlab_1 gitlab-backup create CRON=1

# <＊＊＊必ず最後に改行を入れてください。＊＊＊>
```

正常に動作すると、1日1回（2：00）にバックアップが作成され、一週間が過ぎたバックアップファイルは削除されるようになります。

```shell:
$ ls -la /srv/gitlab/data/backups/
total 16012
drwx------.  2 libstoragemgmt root       4096 Dec  3 02:00 .
drwxr-xr-x. 22 root           root       4096 Nov 25 10:11 ..
-rw-r--r--.  1 libstoragemgmt polkitd 2222080 Nov 27 02:00 1574787621_2019_11_26_12.3.5_gitlab_backup.tar
-rw-r--r--.  1 libstoragemgmt polkitd 2222080 Nov 28 02:00 1574874021_2019_11_27_12.3.5_gitlab_backup.tar
-rw-r--r--.  1 libstoragemgmt polkitd 2385920 Nov 29 02:00 1574960421_2019_11_28_12.3.5_gitlab_backup.tar
-rw-r--r--.  1 libstoragemgmt polkitd 2385920 Nov 30 02:00 1575046821_2019_11_29_12.3.5_gitlab_backup.tar
-rw-r--r--.  1 libstoragemgmt polkitd 2385920 Dec  1 02:00 1575133220_2019_11_30_12.3.5_gitlab_backup.tar
-rw-r--r--.  1 libstoragemgmt polkitd 2385920 Dec  2 02:00 1575219621_2019_12_01_12.3.5_gitlab_backup.tar
-rw-r--r--.  1 libstoragemgmt polkitd 2385920 Dec  3 02:00 1575306021_2019_12_02_12.3.5_gitlab_backup.tar
```

## 設定ファイルの定期バックアップ
backupsの中にconfigディレクトリを作成し、設定ファイルのバックアップを行います。バックアップの方法はtarコマンドを使います。バックアップファイルのファイル名はアプリケーションデータのバックアップファイル名に合わせるために、dateコマンドを利用します。`--date '1 day ago'`をつける事で１日前の日付を取得できます。１週間経過した設定ファイルのバックアップについても削除します。

```vim:
# lオプションでcrontabに設定したコマンドを表示
$ crontab -l

# Creating backup archive
0 2 * * * docker exec -t gitlab_gitlab_1 gitlab-backup create CRON=1
# Create config backup archive
0 2 * * * tar cfz /srv/gitlab/data/backups/config/$(date --date '1 day ago' "+\%s_\%Y_\%m_\%d_12.3.5_gitlab_etc.tar.gz") -C /srv/gitlab config
# Delete old config backups
0 2 * * * find /srv/gitlab/data/backups/config -mtime +6 | xargs rm -rf
```

## バックアップコマンドをスクリプトにまとめる
実行したコマンドをスクリプトにまとめます。**注意が必要な点は、設定ファイルのバックアップファイル名に`\%s_\%Y_\%m_\%d`と記述しましたが、シェルスクリプトでは、バックスラッシュは不要です。**

```bash:gitlab_backup.sh
#!/bin/sh

BKDIR=/srv/gitlab/data/backups

# Creating backup archive
docker exec -t gitlab_gitlab_1 gitlab-backup create

# Create config backup archive
tar cfz $BKDIR/config/$(date --date '1 day ago' "+%s_%Y_%m_%d_12.3.5_gitlab_etc.tar.gz") -C /srv/gitlab config

# Delete old config backups
find $BKDIR/config -mtime +6 | xargs rm -rf

```

crontabはこの様になります。

```vim:
$ crontab -l

# Creating backup archive
# 0 2 * * * docker exec -t gitlab_gitlab_1 gitlab-backup create CRON=1
# Create config backup archive
# 0 2 * * * tar cfz /srv/gitlab/data/backups/$(date "+\%s_\%Y_\%m_\%d_12.3.5_gitlab_etc.tar.gz") -C /srv/gitlab config
# Delete old config backups
# 0 2 * * * find /srv/gitlab/data/backups/config -mtime +6 | xargs rm -rf
0 2 * * * <ファイルパス>/gitlab_backup.sh CRON=1
```

## 最後に
お疲れ様です。これで定期バックアップが可能になり、安心したGitLabライフを満喫できます。

## ご参考
* [GitLab公式ドキュメント「Backing up and restoring GitLab」](https://docs.gitlab.com/ee/raketasks/backup_restore.html)