GitlabをDocker上に引っ越し

Gitlabを立てているサーバのHDD残容量がかなり少なくなったため、前々からやろうと思っていたけどできていなかった、Docker上への引っ越しをようやく実施しました。
Docker上で構築しておくと、アップグレードも簡単というメリットがあります。今回、移行後についでに7.0.0⇒7.6.2へとアップグレードも行いましたけどかなり楽でした。

以下、移行手順のメモです。

移行先Gitlabの構築

移行先となるGitlab本体は再構築する必要がありますが、Docker上に構築するのでDocker Hubにあるものを利用して簡単に構築できます。今回は一番利用されていそうなsameersbn/gitlabを使用させて頂きました。

データベースにはMySQLを使っていたので、移行後もMySQLを使うことにしました。このMySQLも今回、Docker上に移行します。

なお、MySQLやGitリポジトリデータなど、各種Dockerコンテナのデータで永続化する必要があるものは、Dockerホストに配置する方式にしています(docker runの-vオプションでディレクトリを指定)。

MySQLを構築&起動

sameersbn/gitlab のドキュメントに書かれているDockerのLink機能を使った方法で構築します。

# MySQLコンテナ取得
docker pull sameersbn/mysql:latest

# Dockerホスト上で永続データの配置ディレクトリ作成
mkdir /home/core/gitlab_mysql_data

# MySQLコンテナ起動
docker run --name=gitlab-mysql -d \
  -e 'DB_NAME=gitlabhq_production' -e 'DB_USER=gitlab' -e 'DB_PASS=password' \
  -v /home/core/gitlab_mysq_data:/var/lib/mysql \
  sameersbn/mysql:latest

Redisを構築&起動

GitlabではRedisも必要になります。MySQLと同様に、DockerのLink機能を使った方法で構築します。

# Redisコンテナ取得
docker pull sameersbn/redis:latest

# Redisコンテナ起動
docker run --name=gitlab-redis -d sameersbn/redis:latest


MySQLとRedisの準備ができたら、Gitlab本体の構築です。安全に移行するために、移行元と同バージョンの7.0.0でまずは構築(docker pull)します。後はdocker runの--linkオプションでMySQLとRedisに繋げて起動させればOKです。ここが一番重要なポイントで、docker runコマンドの-eオプションで、Gitlabの各種設定(メール送信設定やタイムゾーン設定など)を行う必要があります。
利用可能なパラメータ一覧はこちらにあります。
また、-v /etc/localtime:/etc/localtime:ro を付与することにより、ホストOSのタイムゾーンをDockerコンテナに同期させています。Gitlabコンテナに用意されているcronによるバックアップを走らせる場合は、タイムゾーンをそろえておいたほうが設定しやすいです。

Gitlab 7.0.0を構築

# Gitlabコンテナ取得
docker pull sameersbn/gitlab:7.0.0

# Dockerホスト上で永続データの配置ディレクトリ作成
mkdir /home/core/gitlab_data

Gitlab 7.0.0を色々オプションをつけて起動

docker run --name=gitlab -d --link gitlab-mysql:mysql \
  --link gitlab-redis:redisio \
  -p 10022:22 -p 80:80 \
  -e "GITLAB_PORT=80" -e "GITLAB_SSH_PORT=10022" \
  -e "DB_USER=gitlab" -e "DB_PASS=password" \
  -e "DB_NAME=gitlabhq_production" \
  -e "GITLAB_HOST=xxx.xxx.xxx.xxx" -e "GITLAB_EMAIL=gitlab@example.org" -e "GITLAB_SUPPORT=support-gitlab@example.org" \
  -e "SMTP_ENABLED=true" \
  -e "SMTP_HOST=yyy.yyy.yyy.yyy" -e "SMTP_PORT=25" -e "SMTP_STARTTLS=false" -e "SMTP_DOMAIN=example.org" \
  -e "GITLAB_PROJECTS_VISIBILITY=public" \
  -e "GITLAB_BACKUPS=daily" -e "GITLAB_BACKUP_EXPIRY=172800" \
  -e "NGINX_MAX_UPLOAD_SIZE=100m" \
  -e "GITLAB_TIMEZONE=Tokyo" \
  -v /home/core/gitlab_data:/home/git/data \
  -v /etc/localtime:/etc/localtime:ro \
  sameersbn/gitlab:7.0.0

上記例だと、80ポートを外部に公開しているので、これで http://DockerのホストIP:80 にアクセスするとGitlabにアクセスできるようになります。移行先のGitlabが構築できましたので、続いてデータの移行を行います。

データ移行

Gitlabにはバックアップとリストア用のコマンドが用意されているのでデータの移行は簡単です。ドキュメントはここ

バックアップの実行

移行元の環境で実行します。

sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production

バックアップしたファイルを再構築したサーバに転送

scp /home/git/gitlab/tmp/backups/1420041115_gitlab_backup.tar core@xxx.xxx.xxx.xxx:/home/core/gitlab_data/backups/

バックアップファイルでリストア実行

移行先のDockerホストでの作業になります。リストアコマンドはGitlabに付属しているrakeタスクを使うのですが、docker pullしたGitlabコンテナを利用して実行することができます。

# 一旦動いているGitlabコンテナを停止
docker stop gitlab

# リストアコマンドとともにGitlabコンテナを新規に開始
docker run --name=gitlab -it --rm --link gitlab-mysql:mysql \
  --link gitlab-redis:redisio \
  -e "DB_USER=gitlab" -e "DB_PASS=password" \
  -e "DB_NAME=gitlabhq_production" \
  -v /home/core/gitlab_data:/home/git/data \
  -v /etc/localtime:/etc/localtime:ro \
  sameersbn/gitlab:latest app:rake gitlab:backup:restore

上記コマンドを実行するとどのファイルでリストアするのか聞かれるので、移行対象のファイル名を入力して実行します。
また、下記のように最後にauthorized_keysの上書き確認がされるので、yesで続けます(リストアのキーで上書きする)。

This will rebuild an authorized_keys file.
You will lose any data stored in authorized_keys file.
Do you want to continue (yes/no)? yes

移行確認

docker start gitlab

で再度gitlabを起動し、データが移行されていることを確認して完了です。

バージョンアップ

7.0.0から最新の7.6.2にアップグレードします。
こちらに手順が書かれています。

やることは簡単で、動いているGitlabコンテナを停止・削除し、バックアップの取得、新しいバージョンのGitlabコンテナでrunしてあげるだけです。初回起動時に、自動的にデータベースのマイグレーションが行われます。

# 新しいバージョンのGitlabコンテナ取得
docker pull sameersbn/gitlab:7.6.2

# 既存のコンテナ停止&削除
docker stop gitlab
docker rm gitlab

# バックアップの実行
docker run --name=gitlab -it --rm --link gitlab-mysql:mysql \
  --link gitlab-redis:redisio \
  -e "DB_USER=gitlab" -e "DB_PASS=password" \
  -e "DB_NAME=gitlabhq_production" \
  -v /home/core/gitlab_data:/home/git/data \
  -v /etc/localtime:/etc/localtime:ro \
  sameersbn/gitlab:latest app:rake gitlab:backup:create

# 新しいバージョンのGitlabコンテナを起動
docker run --name=gitlab -d --link gitlab-mysql:mysql \
  --link gitlab-redis:redisio \
  -p 10022:22 -p 80:80 \
  -e "GITLAB_PORT=80" -e "GITLAB_SSH_PORT=10022" \
  -e "DB_USER=gitlab" -e "DB_PASS=password" \
  -e "DB_NAME=gitlabhq_production" \
  -e "GITLAB_HOST=xxx.xxx.xxx.xxx" -e "GITLAB_EMAIL=gitlab@example.org" -e "GITLAB_SUPPORT=support-gitlab@example.org" \
  -e "SMTP_ENABLED=true" \
  -e "SMTP_HOST=yyy.yyy.yyy.yyy" -e "SMTP_PORT=25" -e "SMTP_STARTTLS=false" -e "SMTP_DOMAIN=example.org" \
  -e "GITLAB_PROJECTS_VISIBILITY=public" \
  -e "GITLAB_BACKUPS=daily" -e "GITLAB_BACKUP_EXPIRY=172800" \
  -e "NGINX_MAX_UPLOAD_SIZE=100m" \
  -e "GITLAB_TIMEZONE=Tokyo" \
  -v /home/core/gitlab_data:/home/git/data \
  -v /etc/localtime:/etc/localtime:ro \
  sameersbn/gitlab:7.6.2

Gitlabはバージョンアップ時に依存ライブラリが増えたりとかRubyのバージョンアップが必要になるケースがあるのですが、このようにDocker上で構築しておくと、docker pullするだけでアップグレード完了なのでかなり楽になるかと思います!!