はじめに
手元でサクッとGitLab環境を試したい、そんな時ってありますよね。例えば、以下のような目的で利用する際に便利です。
- 新機能の検証: 新しいGitLabのバージョンがリリースされた際に、本番環境へ適用する前に機能を試す。
- CI/CDの学習: GitLab CI/CDを実際に手を動かしながら学ぶための実験環境として利用する。
- オフライン環境での利用: インターネットに接続できない環境でGitリポジトリを管理する。
本記事では、Docker Composeを使って手軽にGitLab環境を構築する方法をご紹介します。この方法のメリットは、手軽に立ち上げつつも、GitLabのデータ(リポジトリや設定など)をホスト側に永続化できる点です。コンテナを停止・破棄してもデータは残るため、気軽に環境の起動・停止や再構築ができます。
構成
特徴
今回の構成の主な特徴は、フロントにnginxをリバースプロキシとして配置し、SSL通信の終端(SSLターミネーション)を担わせる点です。これにより、GitLab本体はHTTPで通信し、クライアントとの通信はHTTPSで暗号化といった構成が容易に実現できます。証明書の更新などの管理をGitLabと関係なく実施できますし、GitLab側を入れ替えることも容易です。
概要図
全体の構成は以下の図のようになります。
リバースプロキシ
- nginx: リバースプロキシとして、外部からのアクセスをGitLabコンテナとMailDevに振り分けます。またSSOの検証のためKeycloakを動かしていて、それにもアクセスできるようにします。Keycloakについては本記事では触れません。
コンテナ
今回は以下のコンテナを連携させて利用します。
- GitLab: GitLab本体です。Community Edition (CE) を利用します。後述しますが、Enterprise Edition (EE)のFree Editionをご利用になる方がいい場合もあるかもしれません。
- GitLab Runner: CI/CDパイプラインのジョブを実行するコンポーネントです。
- MailDev: GitLabが送信するメール(ユーザー登録通知やCI/CDのエラー通知など)を開発中に確認するためのダミーSMTPサーバーです。キャッチオールタイプで、メールアドレスに関係なく全てのメールがWebメールのUIで確認できます。
実際の構成
具体的な構築手順は、GitLabの公式ドキュメントも参考にしてください。
ホスト側のディレクトリ構成
まず、ホスト側に設定ファイルやデータを格納するためのディレクトリを作成します。
.
├── docker-compose.yml
├── config/
├── data/
├── logs/
├── config-runner/
└── maildev/
docker-compose.yml
次に、docker-compose.yml
を作成します。
services:
gitlab:
image: gitlab/gitlab-ce:18.1.1-ce.0
restart: unless-stopped
ports:
- '8929:80' # Webポートはホスト側で未使用のものにマッピング
- '2424:22' # SSHはポートを変更してホストとマッピング
- '5050:5050' # レジストリ
volumes:
- './config:/etc/gitlab'
- './logs:/var/log/gitlab'
- './data:/var/opt/gitlab'
shm_size: '256m'
networks:
- gitlab-network
gitlab-runner:
image: gitlab/gitlab-runner:latest
volumes:
- './config-runner:/etc/gitlab-runner'
- '/var/run/docker.sock:/var/run/docker.sock'
restart: unless-stopped
networks:
- gitlab-network
maildev:
image: maildev/maildev
ports:
- '1080:1080'
- '1025:1025'
volumes:
- ./maildev:/home/maildev:rw
environment:
- MAILDEV_MAIL_DIRECTORY=/home/maildev
restart: unless-stopped
networks:
- gitlab-network
networks:
gitlab-network:
driver: bridge
GitLab設定 (config/gitlab.rb
)
GitLabの基本設定はdocker-compose.yml
内のenvironment
に書くこともできますが、変更を反映するためにコンテナを再起動する必要があるため、今回はconfig/gitlab.rb
に書くことにしました。変更の反映はコンテナの再起動、またはコンテナ内でgitlab-ctl reconfigure
とします。
# 外部向けのURL (nginxのリバースプロキシのURL)
external_url 'https://gitlab.example.jp'
# GitLabコンテナの入り口の、内蔵nginxの設定
# SSLを使わずHTTPで80番ポートで待ち受け
letsencrypt['enable'] = false
nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['referrer_policy'] = 'same-origin'
# コンテナやパッケージのレジストリ (オプション)
gitlab_rails['registry_enabled'] = true
registry_external_url 'https://gitlab.example.jp:5050'
registry_nginx['listen_https'] = false
# GitLabコンテナへのSSHポート
gitlab_rails['gitlab_shell_ssh_port'] = 2424
# MailDevにメールを送信する設定
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = 'maildev'
gitlab_rails['smtp_port'] = 1025
gitlab_rails['smtp_tls'] = false
gitlab_rails['smtp_openssl_verify_mode'] = 'none'
gitlab_rails['smtp_enable_starttls_auto'] = false
gitlab_rails['smtp_ssl'] = false
gitlab_rails['smtp_force_ssl'] = false
GitLabの起動と初期設定
設定ファイルが準備できたら、いよいよGitLabを起動します。
-
コンテナの起動
docker-compose.yml
があるディレクトリで、以下のコマンドを実行してコンテナをバックグラウンドで起動します。docker compose up -d
-
コンテナの状態確認
コンテナが正常に起動しているか確認します。
gitlab
、gitlab-runner
、maildev
の3つのコンテナがUp
状態で表示されるはずです。GitLab本体は起動に数分かかることがあります。docker compose ps
-
初期パスワードの確認
初回起動時、
root
ユーザーの初期パスワードが自動生成されます。以下のコマンドでパスワードを確認できます。パスワードが表示されるまで少し時間がかかる場合があります。初期パスワードはコンテナ作成後24時間有効です。# パスワードがファイルに書き出されるのを少し待ってから実行してください docker compose exec -it <gitlab_container_name> grep 'Password:' /etc/gitlab/initial_root_password
-
ログイン
ブラウザで
https://gitlab.example.jp
にアクセスします。ログイン画面が表示されたら、ユーザー名「root
」と上記で確認したパスワードでログインします。ログイン後、速やかにパスワードを変更することをお勧めします。
nginx設定
【重要】構成の前提
本記事のnginx設定は、Dockerコンテナが動作するホストと、nginxリバースプロキシが動作するホストが別々に存在することを前提としています。
-
gitlab.example.jp
: ユーザーがアクセスする外部公開用のドメイン名です。 -
gitlab-host.local
: Dockerコンテナが動作しているホストのIPアドレス、または名前解決できるホスト名を指します。
この構成のため、docker-compose.yml
ではGitLabの各ポートをホストに公開し、nginxからはgitlab-host.local
に対してリクエストをプロキシします。
HTTP/HTTPSプロキシ (/etc/nginx/conf.d/gitlab.conf
)
Webアクセスやレジストリアクセスをプロキシするための設定です。
upstream gitlab {
server gitlab-host.local:8929;
}
upstream gitlab-registry {
server gitlab-host.local:5050;
}
upstream mail {
server gitlab-host.local:1080;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name gitlab.example.jp;
ssl_certificate /etc/letsencrypt/live/example.jp/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.jp/privkey.pem;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-port $server_port;
proxy_pass http://gitlab$request_uri;
proxy_redirect off;
}
location ~/maildev(.*)$ {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-port $server_port;
proxy_pass http://mail$1;
proxy_redirect off;
}
}
server {
listen 5050 ssl;
listen [::]:5050 ssl;
server_name gitlab.example.jp;
ssl_certificate /etc/letsencrypt/live/example.jp/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.jp/privkey.pem;
client_max_body_size 500M;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-port $server_port;
proxy_pass http://gitlab-registry$request_uri;
proxy_redirect off;
}
}
SSHプロキシ (/etc/nginx/nginx.conf
)
GitのSSHアクセス (git clone git@gitlab.example.jp:2424/...
) を可能にするには、nginxのメイン設定ファイルにstream
ブロックを追記して、TCPトラフィックをプロキシします。
注意: このstream
ブロックは、http
ブロックの外側(同じ階層)に記述する必要があります。
# /etc/nginx/nginx.conf などに追記
stream {
upstream gitlab-ssh {
server gitlab-host.local:2424;
}
server {
listen 2424; # nginxが待ち受けるSSHポート
listen [::]:2424;
proxy_pass gitlab-ssh;
}
}
GitLab Runnerの登録
GitLab Runnerはコンテナを起動しただけでは使えず、GitLabインスタンスへの登録作業が必要です。
- GitLabに管理者アカウントでログインし、
Admin Area
>CI/CD
>Runners
で登録トークンを確認します。 - 以下のコマンドでRunnerを登録します。nginxでHTTPS化しているため、
--url
にはhttps
のURLを指定します。
# <runner_container_name>は docker ps で確認したRunnerコンテナ名に置き換えてください
docker exec -it <runner_container_name> gitlab-runner register \
--non-interactive \
--url "https://gitlab.example.jp/" \
--registration-token "YOUR_REGISTRATION_TOKEN" \
--executor "docker" \
--docker-image alpine:latest \
--description "My Docker Runner" \
--tag-list "docker,shared" \
--run-untagged="true" \
--locked="false"
トラブルシュート
コンテナ内で問題が発生した場合、gitlab-ctl
コマンドが非常に役立ちます。
# コンテナに入る
docker exec -it <gitlab_container_name> bash
# 各コンポーネントの動作状況を確認する
gitlab-ctl status
# 設定を再読み込み
gitlab-ctl reconfigure
# ログを確認
gitlab-ctl tail
バージョンアップ
この例ではバージョン17.10を使っており、「至急更新ください」と表示されています。

Dockerイメージを利用している場合、バージョンアップは比較的簡単です。
基本的には、docker-compose.yml
のイメージタグを更新し、docker-compose pull
と docker-compose up -d
を実行するだけです。
ただし、一度にメジャーバージョンを複数スキップしてアップグレードすることはできません。必ず推奨されるアップグレードパスを確認してください。
上記ツールでアップグレードパスが確認できます。バージョンの差が大きいほど、バージョンアップの回数が増えますので、こまめにアップデートすることをお勧めします。

docker-compose.yml
では、イメージの指定にlatest
タグを使うのではなく、17.1.1-ce.0
のように具体的なバージョンタグを明示することを強くお勧めします。
タグの一覧はDocker Hubで確認できます。
- Community Edition: https://hub.docker.com/r/gitlab/gitlab-ce/tags/
- Enterprise Edition: https://hub.docker.com/r/gitlab/gitlab-ee/tags/
CEからEEへの移行(またはその逆)
CE (Community Edition) から EE (Enterprise Edition) へ移行や、その逆のダウングレードも可能です。詳細は公式ドキュメントを参照してください。
CEとEEのFree版は、機能的な差異は無いということですので、EEのコンテナイメージを使用して、Free版として使うのが良いのではと思います。もし今後正式にチーム開発に導入してライセンスを購入するようなことになれば、EEにしておけばライセンスキーを入れるだけでPremium/Ultimateになります。
まとめ
本記事では、Docker Composeとnginxリバースプロキシを利用して、柔軟で実践的なGitLab環境を構築する方法を解説しました。
- Docker Composeによる簡単な環境構築とデータ永続化
- nginxを別ホストに立て、リバースプロキシとして利用
- HTTP/HTTPSだけでなく、GitのSSHアクセスもnginxでプロキシ
- GitLab Runnerを登録し、CI/CDを実行する準備
- 安全なバージョンアップのためのアップグレードパスの確認
この構成をベースに、ぜひ快適なGitLabライフをお送りください。