（メモ）Dockerで動かしているGitLabのバックアップと復元


Named Volumeのバックアップと復元でつまづいたので備忘録として。

# 環境

* Docker for Windowsを利用
* Docker version 18.06.0-ce, build 0ffa825
* 日本語化パッチ適用済み： [DockerでのGitLab構築時に自動で日本語化パッチをあてる - Qiita](https://qiita.com/tosier/items/8342e6d968f64f0f79a9)

上記リンクのdockerfileをそのまま流用してイメージを作成しています。

```powershell
> docker build -t gitlab-i18n-patch .
```

docker-compose.ymlは以下のような感じです。permissionの関係で/var/opt/gitlabのみNamed Volumeを割り当てています。

```yaml
version: '3'
services:
  gitlab:
    image: gitlab-i18n-patch:latest
    container_name: gitlab
    restart: always
    ports:
      - '8000:80'
    volumes:
      - /f/docker/gitlab/config:/etc/gitlab
      - /f/docker/gitlab/logs:/var/log/gitlab
      - gitlabdata:/var/opt/gitlab
volumes:
  gitlabdata:
```

# バックアップ

## コンテナをイメージとして保存

下記サンプルでは元々のイメージと同じ名前で保存していますが、ここは適宜適切に。

```powershell
#コンテナが停止している状態で作業をする
> docker-compose stop
> docker ps -a
CONTAINER ID        IMAGE                      COMMAND             CREATED             STATUS                       PORTS               NAMES
5d7eabbcd696        gitlab-i18n-patch:latest   "/assets/wrapper"   4 minutes ago       Exited (127) 5 seconds ago                       gitlab

#イメージを作成
# docker commit コンテナIDまたはコンテナ名 イメージ名
> docker commit gitlab gitlab-i18n-patch
sha256:aee3369c1d92074cdb46be6535790bfcbe19bf732913f897bdea4f8d938fe478
> docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
gitlab-i18n-patch           latest              aee3369c1d92        37 seconds ago      1.2GB

#ファイルに保存
# docker save -o ファイル名 イメージ名
> docker save -o docker_backup_20180727.tar gitlab-i18n-patch

#コンテナを削除
> docker-compose down
```

## データを保存

以下はホストに展開されているディレクトリごと保存します。

* /etc/gitlab
* /var/log/gitlab

/var/opt/gitlabはNamed Volumeなので次の手順で保存します。

なお、保存先のディレクトリは予め作成しておく必要があります。

```powershell
#ボリュームを確認
> docker volume ls
DRIVER              VOLUME NAME
local               docker_gitlabdata

#alpineを利用してファイルに保存
# docker run -it --rm -v 対象のNamedVolume:/volume -v 保存先ディレクトリフルパス:/backup alpine tar -cjf /backup/ファイル名 -C /volume ./
> docker run -it --rm -v docker_gitlabdata:/volume -v /f/docker/backup:/backup alpine tar -cjf /backup/docker_gitlabdata.tar.bz2 -C /volume ./
```

# 復元

docker-compose.yml及びバックアップで生成したファイル類を新しいホストに移して作業します。

# イメージの復元

```powershell
#復元するイメージと同じ名前のものがないことを確認する
> docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED             SIZE

# イメージを復元
# docker load -i ファイル名
> docker load -i docker_backup_20180727.tar
> docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
gitlab-i18n-patch           latest              aee3369c1d92        22 minutes ago      1.2GB
```

サンプルではバックアップ時に同じ名前にしているので問題ないですが、docker-compose.ymlの記述とイメージ名が異なる場合は復元後にリネームするかymlを書き換える必要があります。

# データの復元

以下はバックアップしたものをそのままホストのディレクトリに展開します。

* /etc/gitlab
* /var/log/gitlab

/var/opt/gitlabはファイルからNamed Volumeを復元します。

なお、新しいボリュームの名前は「プロジェクト名_docker-composeのvolumesで定義している名前」となります。

```powershell
#alpineを利用してファイルから復元
# docker run -it --rm -v 新しいVolume名:/volume -v 保存先ディレクトリフルパス:/backup alpine sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/ファイル名"
> docker run -it --rm -v docker_gitlabdata:/volume -v /f/docker/backup:/backup alpine sh -c "rm -rf /volume/* /volume/..?* /volume/.[!.]* ; tar -C /volume/ -xjf /backup/docker_gitlabdata.tar.bz2"
> docker volume ls
DRIVER              VOLUME NAME
local               docker_gitlabdata
```

上記を行ったあと元のホストと同様にdocker-composeで起動すれば復元できているはずです。

# 参考

* [Gitlab docker container – backup and restore | khmel.org](http://khmel.org/?p=1213)
* [Backup & Restore Docker Named Volumes | Jarek Lipski](https://loomchild.net/2017/03/26/backup-restore-docker-named-volumes/)