Dockerを用いたGitLabサーバのオンプレミス構築

GitLabのオンプレミス構築したいけど,
インストールや移行とか「管理」を考えると面倒くさい...

Docker版GitLabなら「管理」が楽になります!

この記事では,以下について記述しています
  • Dockerを用いたGitLab構築
  • HTTPS化
  • メールサーバの設定
  • コンテナレジストリの設定
  • バックアップとリストア

詳しくは目次↓を

目次

オンプレミス構築のメリット・デメリット

メリット

  • セキュリティ関係上,クラウドを用いることが出来ない場合に使用可能
  • マシンスペックを調整可能なため,安定性の向上や高速化が期待できる
  • オンプレミスのため,サーバやネットワーク独自のセキュリティ要件やシステム構成を満たすことが可能
  • クラウドでは編集不可能な設定ファイルを編集することで,独自のサーバーサイドフックなどが設定可能

デメリット

  • 構築の手間がかかる
  • 有償版においてSaaSとオンプレミスのライセンス料金体系に違いがないため,料金面でメリットを感じない
  • サーバを用意する必要がある
  • 障害対策に常に気を配る必要がある

GitLab Runnerに関しては下記の記事を参考にしてください

Dockerを用いたGitLabの構築の前提環境

本記事では,Dockerを用いたGitLab構築を行うためDockerのインストールは必須です.

Dockerは,一般的なRootful Dockerのインストール方法は公式サイトを参照します.

より安全性の高いRootless Dockerをインストールする場合は下記記事を参考にしてください.

GitLab導入(暗号化なし)

コンテナを起動

まずは簡単のため,暗号化なし(HTTP)のGitlab構築を行います.

docker-compose.yml


version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ee:latest'
    restart: always
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.example.com:8080'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        nginx['listen_port'] = 80
    ports:
      - '8080:80'
      - '2222:22'
    volumes:
      - '/srv/gitlab/config:/etc/gitlab'
      - '/srv/gitlab/logs:/var/log/gitlab'
      - '/srv/gitlab/data:/var/opt/gitlab'

external_urlは適宜ドメイン名もしくはIPアドレスに変更してください.

ポートは8080と2222をそれぞれコンテナのポート番号80と22にマッピングしています.
ホスト側で80と22を直接開放しても良いのであれば,マッピングは不要です.

Windowsの”Docker Desktop for Windows”の場合,マウント先(volumes:)をNTFSとして記述します.
D:\\path\\to\\mount\\srv\\gitlab\\config:/etc/gitlab


docker-compose up -d

起動には結構時間がかかるため,docker-compose psでコンテナの状態を確認します.

runnning (starting)からrunnning (healthy)になるまで待ちます.


docker-compose ps

NAME                COMMAND                  SERVICE             STATUS               PORTS
root-gitlab-1       "/assets/wrapper"        gitlab              running (starting)   0.0.0.0:2222->22/tcp, 0.0.0.0:8080->80/tcp, :::2222->22/tcp, :::2222->80/tcp

NAME                COMMAND                  SERVICE             STATUS               PORTS
root-gitlab-1       "/assets/wrapper"        gitlab              running (healthy)   0.0.0.0:2222->22/tcp, 0.0.0.0:8080->80/tcp, :::2222->22/tcp, :::2222->80/tcp

進捗が知りたければ,docker-compose logsで確認します.

ブラウザに指定したexternal_urlを入力し,アクセスします.

Rootパスワードを設定し,GitLabにアクセスする

コンテナに接続し,GitLabの設定コンソールを開いてRootパスワードを設定します.


docker-compose exec gitlab gitlab-rails console -e production

起動には結構時間がかかりますので,少し待ちます.

この場合,booted in 41.94sと表示されているので,42秒くらい待ちました.


--------------------------------------------------------------------------------
 Ruby:         ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux]
 GitLab:       14.10.2-ee (459b3357007) EE
 GitLab Shell: 13.25.1
 PostgreSQL:   12.7
------------------------------------------------------------[ booted in 41.94s ]
Loading production environment (Rails 6.1.4.7)

コンソール起動後に下記の手順でパスワードを設定します.


irb(main):001:0> user = User.where(id: 1).first
=> #<user id:1 @root>
irb(main):002:0> user.password = 'root_password'
=> "root_password"
irb(main):003:0> user.password_confirmation = 'root_password'
=> "root_password"
irb(main):004:0> user.save!
=> true
irb(main):005:0> exit

root_passwordは設定したいパスワードを入力してください.

弱いパスワードを設定しようとするとエラーとなりますので注意が必要です.

コンソールを閉じて,ブラウザにアクセスします.

ユーザ名はrootで,設定したパスワードでログインを確認してください.

無事アクセスができると下記画面が表示されます.

GitLab構築(暗号化あり)

前提

暗号化を有効化するためには,SSL/TLS証明書を取得している必要があります.

今回は,Let’s Encryptから取得したサーバ証明書を使用してHTTPS化します.

SSL/TLS証明書の発行手順

SSL/TLS証明書の発行手順は下記記事に記載しています.

SSL/TLS証明書のコピー

コンテナのマウント先/etc/ssl/certs/gitlabに,取得したSSL/TLS証明書をコピーします.


cp /etc/letsencrypt/live/your-domain/fullchain.pem /etc/ssl/certs/gitlab/fullchain.pem
cp /etc/letsencrypt/live/your-domain/privkey.pem /etc/ssl/certs/gitlab/privkey.pem

マウント先を直接SSL/TLS証明書の保存場所(/etc/letsencrypt/...)にしても良いですが,安全のためコンテナから分離しておきます.

証明書の更新時のコピーを自動化

SSL/TLS証明書の更新された場合,再度に手動でコピーする必要があります.

手動でコピーするのは保守性が低いため自動化します.

cronにより自動化を行います.


crontab -e

SSL/TLS証明書の更新の直後にコピーを実行するように設定します.


0 3 1 * * certbot renew; cp /etc/letsencrypt/live/your-domain/fullchain.pem /etc/ssl/certs/gitlab/fullchain.pem; cp /etc/letsencrypt/live/your-domain/privkey.pem /etc/ssl/certs/gitlab/privkey.pem; docker-compose restart

SSL/TLS証明書を更新した後はコンテナを更新しないといけないようです.

HTTPS化したGitLabコンテナの構築

Docker-Composeの設定ファイルは下記のようになります.

docker-compose.yml


version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ee:latest'
    restart: always
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.example.com:8080'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        nginx['enable'] = true
        nginx['listen_port'] = 443
        nginx['redirect_http_to_https'] = true
        nginx['ssl_certificate'] = "/etc/ssl/certs/gitlab/fullchain.pem"
        nginx['ssl_certificate_key'] = "/etc/ssl/certs/gitlab/privkey.pem"
        letsencrypt['enable'] = false
    ports:
      - '8080:443'
      - '2222:22'
    volumes:
      - /srv/gitlab/config:/etc/gitlab
      - /srv/gitlab/logs:/var/log/gitlab
      - /srv/gitlab/data:/var/opt/gitlab
      - /etc/ssl/certs/gitlab:/etc/ssl/certs/gitlab
    shm_size: '256m'

暗号化なしのものと比較すると,external_urlのHTTPS化とNgnixの設定を少し変更しています.

また,http://...を指定した場合でも,https://...にリダイレクトする設定になっています.

ブラウザにて,暗号化していることを確認してください.

ログインは,暗号化なしの場合と同様の手順で行います.

Docker版GitLabの運用Tips

メールサーバの設定

GitLabでは,SMTPサーバを利用してメールを送信する機能が搭載されています.

特によく使われる機能は,「CI/CDにおけるテスト失敗時にメールを送信する」機能です.

この機能を有効化するために,SMTPサーバの設定を行います.

前提

メールサーバとして利用するためのSMTPサーバを用意します.

もっとも簡単な方法は,GmailのSMTPサーバを利用して,GitLabからメールを送信する方法です.

Gmailは無料でアカウントを複数作成できるため,GitLabメール通知用アカウントとして利用するのに便利です.

続いて,GmailをSMTPサーバを利用する方法を示します.

SMTPサーバの設定

SMTPサーバの登録をするため,gitlab.rbという設定ファイルを編集します.

gitlab.rb/etc/gitlabに置かれています.

今回はコンテナ内の/etc/gitlab/srv/gitlab/configにマウントしているため,ホストから/srv/gitlab/config/gitlab.rbを編集します.

末尾に下記項目を記述します.

/srv/gitlab/config/gitlab.rb


...
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.gmail.com"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "your-email@gmail.com"
gitlab_rails['smtp_password'] = "your-password"
gitlab_rails['smtp_domain'] = "smtp.gmail.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'peer' # Can be: 'none', 'peer', 'client_once', 'fail_if_no_peer_cert', see http://api.rubyonrails.org/classes/ActionMailer/Base.html

your-email@gmail.comおよびyour-passwordはGmailに登録しているものを利用してください.

gitlab.rbを編集したら,下記コマンドで設定を反映します.


docker-compose exec gitlab gitlab-ctl reconfigure

...
Running handlers:
Running handlers complete
Chef Infra Client finished, 5/812 resources updated in 19 seconds
gitlab Reconfigured!

再起動します.


docker-compose exec gitlab gitlab-ctl restart

右上のアイコンより,[Edit profile]より設定画面を開きます.

メールアドレスを入力すると,SMTPサーバを経由してメールが送信されます.

そのまま使用するとGoogleアカウントのセキュリティの問題でブロックされます.

解消する方法として,Googleアカウントにアクセスして下記のどちらかを行います.

1.「安全性の低いアプリのアクセス」を許可 

※ 2022/05/31から使えなくなりました.二段階認証を使用ください.

2.二段階認証を有効化し,アプリパスワードを使用

↓↓↓二段階認証の設定方法は下記記事にまとめました↓↓↓

無事メールが届けば成功です.

コンテナ作成と同時にSMTPサーバの設定

上記では,コンテナ起動後にgitlab.rbを編集して,有効化する方法を示しました.

しかし,この方法は少々手間なので,コンテナの作成と同時に設定する方法を示します.

gitlab_rails...docker-compose.ymlGITLAB_OMNIBUS_CONFIGに追加するだけです.

docker-compose.yml


version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ee:latest'
    restart: always
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.example.com:8080'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        nginx['listen_port'] = 80
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['smtp_address'] = "smtp.gmail.com"
        gitlab_rails['smtp_port'] = 587
        gitlab_rails['smtp_user_name'] = "your-email@gmail.com"
        gitlab_rails['smtp_password'] = "your-password"
        gitlab_rails['smtp_domain'] = "smtp.gmail.com"
        gitlab_rails['smtp_authentication'] = "login"
        gitlab_rails['smtp_enable_starttls_auto'] = true
        gitlab_rails['smtp_tls'] = false
        gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
    ports:
      - '8080:80'
      - '2222:22'
    volumes:
      - '/srv/gitlab/config:/etc/gitlab'
      - '/srv/gitlab/logs:/var/log/gitlab'
      - '/srv/gitlab/data:/var/opt/gitlab'

管理者のメールアドレスを変更

初期メールアドレスは,admin@example.comに設定されています.

このままでは通知等が受け取れないため,変更する必要があります.

Emailの登録

[User Setting] > [Emails]から,自分のメールアドレスを追加します.

Confirm your email addressをクリックして認証します.

認証が完了したら,”Verified”マークがつきます.

Primary Emailの変更

User Setting] > [Edit Profile]からEmailを変更します.

通知メールアドレスの変更

[User Setting] > [Notification]からNotification emailを設定したメールアドレスに変更します.

古いメールアドレスを削除

一通り設定が完了したら,admin@example.comに設定されていた項目が新しいメールアドレスに設定されます.

すべての項目が設定済みであることを確認し,ごみ箱マークをクリックし,古いメールアドレスを削除します.

バックアップとリストア

手動バックアップの設定


docker-compose exec gitlab gitlab-backup create

生成されるバックアップファイル名は<TIMESTAMP>_gitlab_backup.tarとなります.
<TIMESTAMP>1493107454_2018_04_25_10.6.4-eeのような形式です.
保存先は,/var/opt/gitlab/backups/です.

次に設定ファイルのバックアップをします.

設定ファイルはバックアップは忘れがちですが必ず行ってください.暗号化キーなど機密情報が含まれています

最低限必要なファイルは,/etc/gitlab/gitlab-secrets.json/etc/gitlab/gitlab.rbです.

下記コマンドのようにバックアップします.


docker-compose cp gitlab:/etc/gitlab/gitlab.rb /path/to/backup/on/host
docker-compose cp gitlab:/etc/gitlab/gitlab-secrets.json /path/to/backup/on/host

もしくは設定ファイル全体を下記コマンドでバックアップします.


docker-compose exec gitlab gitlab-ctl backup-etc

/etc/gitlab/ls/gitlab_config_*****.tarというファイルが作成されます.

>> スーパーユーザーなら知っておくべきLinuxシステムの仕組み

自動バックアップの設定

自動バックアップのため,スクリプト実行を行います.

ホストでスクリプト実行したほうが管理が楽なため,コンテナ内のバックアップフォルダをホストにマウントします.

マウント用にDocker Composeファイルの一例を示します.コード内ハイライトが必要な設定です.

docker-compose.yml


version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ee:latest'
    restart: always
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.example.com:8080'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        nginx['listen_port'] = 80
        gitlab_rails['backup_path'] = "/var/opt/gitlab/backups"
        gitlab_rails['backup_keep_time'] = 604800 # 7days
    ports:
      - '8080:80'
      - '2222:22'
    volumes:
      - '/srv/gitlab/config:/etc/gitlab'
      - '/srv/gitlab/logs:/var/log/gitlab'
      - '/srv/gitlab/data:/var/opt/gitlab'
      - '/srv/gitlab/backups:/var/opt/gitlab/backups'

cronによって定期的にバックアップととります.

crontab -e


0 4 * * * cd /path/to/docker-compose.yml; docker-compose exec gitlab gitlab-backup create
0 4 * * * cd /path/to/docker-compose.yml; docker-compose exec gitlab gitlab-ctl backup-etc

バックアップファイルがそれぞれホストの/srv/gitlab/config/config_backup/srv/gitlab/backupsに保存されます.

バックアップ後は適宜別ストレージに移行などの手順を行ってください.

スクリプトによる自動バックアップ

上記では,バックアップコマンドをcronでスケジューリングしましたが,実際には「バックアップファイルの作成」から「保存用ストレージへの転送」を一連の流れで行います.

その手順を実行するスクリプトを一例として作成しました.

backup_gitlab.sh


#!/bin/bash
SCRIPT_DIR=$(cd $(dirname $0); pwd)
cd ${SCRIPT_DIR}
docker-compose exec gitlab gitlab-ctl backup-etc
docker-compose exec gitlab gitlab-backup create
DIR_NAME=gitlab_backup_$(date +%Y_%m_%d)
mkdir -p ${DIR_NAME}
cp /srv/gitlab/config/config_backup/$(ls -t /srv/gitlab/config/config_backup/ | head -n1) ${SCRIPT_DIR}/${DIR_NAME}
cp /srv/gitlab/backups/$(ls -t /srv/gitlab/backups | head -n1) ${SCRIPT_DIR}/${DIR_NAME}
scp -r ${DIR_NAME} server_addr:/path/to/backup

このスクリプトをcronに登録します.

crontab -e


0 4 * * * bash /path/to/backup_gitlab.sh

リストア

流れはとして下記のものになります.

  1. 起動中のGitLabのサービスを停止
  2. バックアップファイルをコンテナ内にコピー
  3. コンテナ内にコピーしたバックアップファイルの権限を変更
  4. 設定ファイルをコンテナ内にコピー,解凍.不要なファイルを削除
  5. GitLabの再構成と再起動

docker-compose exec gitlab gitlab-ctl stop
docker-compose cp  <TIMESTAMP>_gitlab_backup.tar gitlab:/var/opt/gitlab/backups/
docker-compose exec gitlab chown git:git /var/opt/gitlab/backups/<TIMESTAMP>_gitlab_backup.tar
docker-compose cp /path/to/backup/gitlab_config_*****.tar gitlab:/gitlab_config_*****.tar
docker-compose exec gitlab tar xvf /gitlab_config_*****.tar 
docker-compose exec gitlab rm /gitlab_config_*****.tar
docker-compose exec gitlab gitlab-backup restore BACKUP=<TIMESTAMP> GITLAB_ASSUME_YES=1 
docker-compose exec gitlab gitlab-ctl reconfigure
docker-compose exec gitlab gitlab-ctl restart

GitLabのバージョンが異なる場合は,エラーが発生する可能性があります.可能な限りバックアップ時のGitLabのバージョンと同じものを使用した方が良いです.

Container Registoryの有効化

コンテナレジストリを使用する場合は,レジストリを有効化します.(使用しない場合,設定不要です)

手動で有効化

/etc/gitlab/gitlab.rbに下記項目を追加します.


...
registry_external_url 'https://gitlab.example.com:5050'
registry['enable'] = true
registry_nginx['listen_port'] = 5050
registry_nginx['ssl_certificate'] = "/etc/ssl/certs/gitlab/fullchain.pem"
registry_nginx['ssl_certificate_key'] = "/etc/ssl/certs/gitlab/privkey.pem"

設定ファイル変更後に,下記コマンドにて再構成を行います.


docker-compose exec gitlab gitlab-ctl reconfigure

コンテナ作成時に有効化

docker-compose.yml


version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ee:latest'
    restart: always
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.example.com:8080'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        nginx['enable'] = true
        nginx['listen_port'] = 443
        nginx['redirect_http_to_https'] = true
        nginx['ssl_certificate'] = "/etc/ssl/certs/gitlab/fullchain.pem"
        nginx['ssl_certificate_key'] = "/etc/ssl/certs/gitlab/privkey.pem"
        registry_external_url 'https://gitlab.example.com:5050'
        registry_nginx['enable'] = true
        registry_nginx['listen_port'] = 5050
        registry_nginx['ssl_certificate'] = "/etc/ssl/certs/gitlab/fullchain.pem"
        registry_nginx['ssl_certificate_key'] = "/etc/ssl/certs/gitlab/privkey.pem"
        letsencrypt['enable'] = false
    ports:
      - '8080:443'
      - '2222:22'
      - '5555:5050'
    volumes:
      - /srv/gitlab/config:/etc/gitlab
      - /srv/gitlab/logs:/var/log/gitlab
      - /srv/gitlab/data:/var/opt/gitlab
      - /etc/ssl/certs/gitlab:/etc/ssl/certs/gitlab
    shm_size: '256m'
注意点

GitLab上では,コンテナ内のポートが表示されます.

Dockerを介したポートマッピングを行っている場合,マッピング用に開放しているポート番号が表示されません.

わかりやすさを重視すると,ホストとコンテナのポート番号は同じものを使用すると良いでしょう.

まとめ

いろいろと設定に関して記述しましたが,私が使用しているDocker Composeファイルは下記のものです.

docker-compose.yml


version: '3'
services:
  gitlab:
    image: 'gitlab/gitlab-ee:latest'
    restart: always
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'gitlab.example.com:8080'
        gitlab_rails['gitlab_shell_ssh_port'] = 2222
        nginx['enable'] = true
        nginx['listen_port'] = 443
        nginx['redirect_http_to_https'] = true
        nginx['ssl_certificate'] = "/etc/ssl/certs/gitlab/fullchain.pem"
        nginx['ssl_certificate_key'] = "/etc/ssl/certs/gitlab/privkey.pem"
        letsencrypt['enable'] = false
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['smtp_address'] = "smtp.gmail.com"
        gitlab_rails['smtp_port'] = 587
        gitlab_rails['smtp_user_name'] = "your-email@gmail.com"
        gitlab_rails['smtp_password'] = "your-password"
        gitlab_rails['smtp_domain'] = "smtp.gmail.com"
        gitlab_rails['smtp_authentication'] = "login"
        gitlab_rails['smtp_enable_starttls_auto'] = true
        gitlab_rails['smtp_tls'] = false
        gitlab_rails['smtp_openssl_verify_mode'] = 'peer'
        registry_external_url 'https://gitlab.example.com:5050'
        registry['enable'] = true
        registry_nginx['listen_port'] = 5050
        registry_nginx['ssl_certificate'] = "/etc/ssl/certs/gitlab/fullchain.pem"
        registry_nginx['ssl_certificate_key'] = "/etc/ssl/certs/gitlab/privkey.pem"
        gitlab_rails['backup_path'] = "/var/opt/gitlab/backups"
        gitlab_rails['backup_keep_time'] = 604800 # 7days
    ports:
      - '8080:443'
      - '2222:22'
      - '5050:5050'
    volumes:
      - /srv/gitlab/config:/etc/gitlab
      - /srv/gitlab/logs:/var/log/gitlab
      - /srv/gitlab/data:/var/opt/gitlab
      - /srv/gitlab/backups:/var/opt/gitlab/backups
      - /etc/ssl/certs/gitlab:/etc/ssl/certs/gitlab
    shm_size: '256m'

↓↓↓CI/CDのためのGitLab Runnerの設定方法は,下記記事を参考にしてください.↓↓↓

↓↓↓GitLab運用に関しては,下記記事を参考にしてください.↓↓↓

よかったらシェアしてね!
目次