GitLabを社内のサーバーにDockerで構築すると、コマンド1つで起動はできます。ただ、業務で使い続けるには、版の固定、HTTPS、メール送信、バックアップと復元、アップグレードの経路まで事前に決めておくことが必要です。本記事では、Docker ComposeでGitLab CE(Self-Managed)をオンプレ構築する手順を、docker-compose.ymlとgitlab.rbの設定例つきで解説します。後半で示すのは、Dockerでの構築を採用する条件と見送る場面です。版と手順は2026年11月12日時点の公式ドキュメントとDocker Hubの公開情報に基づきます。
まとめ:GitLabのオンプレ構築はDocker Composeと版固定・バックアップ設計で決まる
Docker版GitLabは、公式イメージgitlab/gitlab-ceに、Rails本体・PostgreSQL・Redis・NGINXなどが1つのコンテナとして同梱された形で配布されています。構築作業の大半はdocker-compose.ymlを1枚書くことで、難しいのは起動した後の運用です。
本番で使う前に決めるのは4つです。イメージをlatestではなく版番号で固定すること。gitlab-backup createの結果とは別にgitlab-secrets.jsonを保存すること。復元はバックアップと同じ版のイメージで行うこと。アップグレードは19.5や19.8といった必須経由版を飛ばさないこと。
サーバーは8 vCPU・16GBが公式の基準です。毎月の更新を手順化できる担当者がいない場合は、オンプレ構築ではなくGitLab.comを選んでください。
GitLabをオンプレのDockerで構築する前に決めるサーバー要件とホスト名
8 vCPU・16GBの基準とメモリ8GBで動かすときの設定の削り方
GitLabのインストール要件では、1台構成の基準を8 vCPU・メモリ16GBとしています。メモリが限られる環境の例外として最低8GBが示されているものの、これは一般的な最小値ではないと明記されています。ストレージはアプリケーション用に40GB、リポジトリ用に全リポジトリの合計以上が必要で、Gitalyの入出力が多いためSSDが推奨です。NFSやAmazon EFSのようなネットワークファイルシステムは避けるよう書かれています。
検証機や小規模チームでメモリを抑えたい場合は、メモリ制約環境向けの設定ガイドの値をgitlab.rbに入れます。
# /etc/gitlab/gitlab.rb(メモリ制約環境向けの公式推奨値から抜粋)
puma['worker_processes'] = 0 # Pumaを単一プロセスで動かす
sidekiq['concurrency'] = 10 # Sidekiqの並列数を10に抑える
prometheus_monitoring['enable'] = false # 同梱の監視一式を止める
同ガイドはPumaの単一プロセス化で100〜400MB、監視の停止で300MBのメモリ削減を観測したと報告し、この構成のハードウェア目安を「RAM 2.5GB+スワップ1GB」としています。ただし監視を止めるとPrometheusのメトリクスが取れなくなります。チームで常用する本番環境では、削らずに16GBを用意するほうが運用は楽です。
Docker for Windowsが非対応でlocalhostをホスト名に使えない制約
Docker版のインストール手順は、前提として「Docker for Windowsではない動作するDocker環境」を挙げています。Windows上のDockerで動かす構成はサポート対象外のため、本番用にはLinuxのサーバーを用意してください。
ホスト名にも制約があります。外部から到達できる有効なホスト名が必要で、localhostは使えません。社内DNSにgitlab.example.co.jpのような名前を登録してから構築に入ると、後でURLを変える手戻りが出ません。GitLabはこの名前をクローン用URLやメール本文のリンクに埋め込むため、運用開始後の変更は利用者全員のリモート設定に響きます。
Docker ComposeのGitLab CE起動設定と版固定・永続化の記述例
版を固定したイメージタグとconfig・logs・dataの3ボリューム
公式手順の構成に、本番で必要な2点を加えたのが次の例です。1つはイメージの版固定、もう1つはホストのSSH(22番)と衝突しないようGitのSSHを2222番へずらす設定です。
# 事前準備:設定・ログ・データを置くディレクトリ
sudo mkdir -p /srv/gitlab
export GITLAB_HOME=/srv/gitlab
# /srv/gitlab/docker-compose.yml
services:
gitlab:
image: gitlab/gitlab-ce:19.5.5-ce.0 # latestを使わず版で固定する
container_name: gitlab
restart: always
hostname: 'gitlab.example.co.jp'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.example.co.jp'
gitlab_rails['gitlab_shell_ssh_port'] = 2222
gitlab_rails['backup_keep_time'] = 604800
ports:
- '80:80'
- '443:443'
- '2222:22'
volumes:
- '$GITLAB_HOME/config:/etc/gitlab'
- '$GITLAB_HOME/logs:/var/log/gitlab'
- '$GITLAB_HOME/data:/var/opt/gitlab'
shm_size: '256m'
# 起動(初回は数分かかる)
cd /srv/gitlab && docker compose up -d
公式手順は本番環境では特定の版に固定すべきとし、latestはテスト用と位置づけています。タグは<major>.<minor>.<patch>-ce.0の形式で、2026年11月12日時点のDocker Hubのgitlab-ceタグ一覧では19.5.5-ce.0が最新です。SELinuxが有効なホストでは、ボリューム指定の末尾に:Zを付けないと設定ファイルを作れません。
起動後の初期rootパスワードの取り出しと各サービスの稼働確認は、GitLabとは(構成要素とDockerで試す手順)のコマンドと同じです。本記事ではその先の設定に進みます。
GITLAB_OMNIBUS_CONFIGとgitlab.rbの設定分担・反映方法
設定の書き場所は2つあります。Docker版の設定ドキュメントによると、環境変数GITLAB_OMNIBUS_CONFIGの内容はgitlab.rbより先に評価され、ファイルには書き込まれません。起動のたびに評価し直される値です。
| 書き場所 | 向く設定 | 反映方法 |
|---|---|---|
| 環境変数 | URL・SSHポート | compose up -d |
| gitlab.rb | SMTP・証明書・メモリ調整 | docker restart |
おすすめはポートやURLのようにdocker-compose.ymlのportsと揃える値だけを環境変数に置き、残りをgitlab.rbに寄せる分け方です。両方に同じ項目を書くと、どちらが効いているかを追うのに時間を取られます。gitlab.rbはsudo docker exec -it gitlab editor /etc/gitlab/gitlab.rbで編集でき、コンテナは起動のたびに自身を再設定します。
HTTPSとメール送信を設定してオンプレGitLabを社内へ公開する手順
Let’s Encryptの自動発行と社内CAの証明書を置く場合の設定
GitLabのSSL設定ドキュメントでは、external_urlがhttpsで、ほかの証明書が設定されていない場合にLet’s Encryptが既定で有効になります。条件は80番と443番がLet’s Encryptの検証サーバーから到達できることで、更新は既定で毎月4日の深夜に予定されます。
閉域網のGitLabでは外部から検証できないため、社内CAや購入した証明書を置きます。
# /etc/gitlab/gitlab.rb
letsencrypt['enable'] = false # 自動更新で証明書が上書きされないよう無効にする
# 証明書はホスト名にあわせた名前で置く(ホスト側は $GITLAB_HOME/config/ssl/)
# /etc/gitlab/ssl/gitlab.example.co.jp.crt サーバー証明書→中間証明書の順で連結
# /etc/gitlab/ssl/gitlab.example.co.jp.key 秘密鍵
証明書ファイルの中身だけを差し替えたときは、コンテナ内でgitlab-ctl hup nginxを実行すれば再読み込みされます。チェーンの順序を誤ると、ブラウザでは開けてもgitコマンドやRunnerが証明書エラーで止まります。差し替え後はgit ls-remoteで確かめると確実です。
DockerイメージにSMTPサーバーが無い前提で外部の送信元へつなぐ設定
Docker版の設定ドキュメントには「GitLabのDockerイメージにはSMTPサーバーがあらかじめ入っていない」とあります。未設定のままではパスワード再設定やMRの通知メールが届かず、利用者を招待した段階で支障が出るため、送信先の指定が必要です。社内のメールサーバーやSendGridなどの送信サービスをSMTP設定ドキュメントのキーで指定します。
# /etc/gitlab/gitlab.rb(値は自社の送信サーバーに置き換える)
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.example.co.jp"
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = "<SMTPユーザー名>"
gitlab_rails['smtp_password'] = "<SMTPパスワード>"
gitlab_rails['smtp_domain'] = "example.co.jp"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['gitlab_email_from'] = '<送信元アドレス>'
# 反映後、Railsコンソールからテストメールを送る
# sudo docker exec -it gitlab gitlab-rails console
# Notify.test_email('<宛先アドレス>', 'テスト', '本文').deliver_now
465番ポート(SMTPS)を使う送信サーバーならsmtp_tlsをtrueにします。パスワードに'のような文字列の区切り文字が入っているとRubyの設定として読めなくなるため、使わない値で発行し直してください。
オンプレGitLabのバックアップと復元をDocker環境で回す手順
バックアップとgitlab-secrets.jsonの別保存が必要になる理由
Docker版のバックアップ手順では、ホストからdocker exec -t gitlab gitlab-backup createを実行します。出力先はコンテナ内の/var/opt/gitlab/backupsで、先の例ならホストの/srv/gitlab/data/backupsに残ります。
見落とされやすいのは、このアーカイブに設定ファイルが入らない点です。バックアップの公式ドキュメントは、/etc/gitlabの設定ファイル、TLSとSSHの鍵、Redisが対象外だと明記しています。中でもgitlab-secrets.jsonにはデータベースの暗号化キーが入っています。これを失うと、CI/CDの変数や二要素認証の値を復号できません。
実務上の優先順位は、リポジトリとDBのアーカイブ、gitlab-secrets.json、gitlab.rbとSSHホスト鍵の順です。前の2つが揃わないと復元が成立しません。アーカイブとgitlab-secrets.jsonは同じ場所に置かず、保管先を分けるとアーカイブが漏れても暗号化された値までは読まれません。
cronで毎日2時に取得し7日で消すbackup_keep_timeの設定例
公式ドキュメントはLinuxパッケージ向けに0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON=1を例示しています。Docker版ではこれをdocker exec経由に置き換え、ホストのrootのcrontabに登録します。
# ホストの root crontab(sudo crontab -e)
# 02:00 アプリケーションデータのバックアップ(CRON=1 はエラー時以外の出力を抑える)
0 2 * * * docker exec -t gitlab gitlab-backup create CRON=1
# 02:30 設定とシークレットを日付つきで別の保管先へ
30 2 * * * tar czf /mnt/backup-config/gitlab-config-$(date +\%F).tgz -C /srv/gitlab config
古いアーカイブの削除は、docker-compose.ymlに入れたgitlab_rails['backup_keep_time'] = 604800(7日)が受け持ちます。この設定はローカルのファイルにしか効かないと明記されており、S3などへ転送した先の世代管理を受け持つのはストレージ側のライフサイクル設定です。cronの%はエスケープしないと改行として扱われるため、上の例では\%と書いています。
同じ版のイメージで復元するgitlab-backup restoreの実行順
復元の公式ドキュメントは、復元先がバックアップと同じ版・同じエディションであることを前提にしています。19.5.5で取ったアーカイブは19.5.5-ce.0のイメージに戻すので、イメージを版で固定しておく意味がここで効いてきます。
# 1) 新しいホストに同じ版でGitLabを起動し、gitlab-secrets.json を config へ戻しておく
# 2) DBに接続するプロセスを止める
docker exec -it gitlab gitlab-ctl stop puma
docker exec -it gitlab gitlab-ctl stop sidekiq
docker exec -it gitlab gitlab-ctl status
# 3) 復元(ファイル名の _gitlab_backup.tar は付けない)
docker exec -it gitlab gitlab-backup restore BACKUP=<タイムスタンプ>_<日付>_19.5.5
# 4) 再起動して整合性を点検する
docker restart gitlab
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true
公式手順は再起動の前に、復元したデータベースへANALYZEを実行して統計情報を集めることも挙げています。復元手順は障害が起きてから初めて試すと、版の不一致やsecretsの欠落に気づくのが遅れます。四半期に1回、検証用ホストへ実際に戻してログインとクローンまで確かめる運用にしてください。
Docker版GitLabのアップグレードは必須経由版の19.5・19.8を守って上げる
docker compose pullで上げる手順と事前に取るバックアップの範囲
Docker版のアップグレード手順は3段階です。最低限データベースとシークレットファイルをバックアップし、docker-compose.ymlのイメージの版を書き換え、新しいイメージを取得して作り直します。
# 1) 事前バックアップ(公式手順のDBのみバックアップ)
docker exec -t gitlab gitlab-backup create \
SKIP=artifacts,repositories,registry,uploads,builds,pages,lfs,packages,terraform_state
cp /srv/gitlab/config/gitlab-secrets.json /mnt/backup-config/
# 2) docker-compose.yml の image を次の版へ書き換える(例:19.5.4-ce.0 → 19.5.5-ce.0)
# 3) 取得して作り直す
cd /srv/gitlab
docker compose pull
docker compose up -d
# 4) 未完了のバッチ型バックグラウンドマイグレーションを確認する(0行なら完了)
docker exec -it gitlab gitlab-psql -c \
"SELECT job_class_name, table_name FROM batched_background_migrations WHERE status NOT IN(3, 6);"
手順4の結果が0行になるまでは、次のマイナー版へ進みません。バックグラウンドマイグレーションのドキュメントは、アップグレード前にすべてのマイグレーションがFinishedになっている必要があるとしています。版をまたいで連続で上げるときほど、この確認を省きがちです。更新の頻度はリリースと保守のポリシーに従い、マイナー版が毎月出て、セキュリティ修正の対象は直近3つのマイナー版です。2026年10月29日に公開された19.5.3などのパッチリリースでも、GitLab社はすべてのSelf-Managedをいずれかの修正版へ上げるよう強く推奨しています。緊急パッチが出たときの判断はGitLab脆弱性の対応手順と修正版の判断基準で扱っています。
アップグレードストップとUpgrade Path toolで経由する版を決める方法
マイナー版を飛ばして上げられる範囲には限りがあります。アップグレードパスの公式ドキュメントは、必ず経由する版(アップグレードストップ)を次のように定めています。
| メジャー版 | 必ず経由する版 |
|---|---|
| 19.x | 19.2・19.5・19.8・19.11 |
| 18.x | 18.2・18.5・18.8・18.11 |
| 17.x | 17.3・17.5・17.8・17.11 |
19.8と19.11は2026年11月12日時点で未リリースです。17.xは経由する版がパッチまで指定されており、17.3.7・17.5.5・17.8.7・17.11.7が経由先です。ci_pipeline_messagesテーブルが大きい環境に限り17.1.8も加わります。たとえば18.6で止まっている環境を19.5へ上げるなら、18.8、18.11、19.2を順に経由します。現在の版と目標の版を入れると経路を計算するUpgrade Path toolをGitLab Supportが公開しているので、作業計画はこの出力を貼り付けて作ると漏れません。19.x系はPostgreSQL 17.x〜18.xが前提のため、18.x系から上げるときはdocker exec -it gitlab gitlab-psql -c 'SELECT version();'で同梱DBの版も確認してください。18.10を起点にした実際の移行経路はGitLab 18.10から19.4・19.5への移行経路にまとめています。
Docker構築を採用する条件とLinuxパッケージ・GitLab.comを選ぶ場面
Dockerでのオンプレ構築を採用するのは更新を手順化できる組織
Dockerでの構築が向くのは、ソースコードを社外のSaaSに置けない規程があり、かつ上で示した更新とバックアップをRunbookに落として毎月回せる組織です。版をdocker-compose.ymlの1行で管理でき、同じ版のイメージを別ホストで起動して復元訓練できる点は、Linuxパッケージを直接入れる構成より扱いやすい部分です。
CIのジョブを動かすRunnerは本体と別のホストに置きます。登録とexecutorの選び方はGitLab Runnerの登録手順とconfig.tomlの設定例、パイプラインの書き方はGitLab CI/CDの.gitlab-ci.ymlの設定例を参照してください。
利用者が数百人規模になり、Gitalyやデータベースを分けた複数台構成が必要になったら、1コンテナのDocker版は卒業の時期です。公式もKubernetesへの直接デプロイは単一障害点になるとして推奨しておらず、その規模ではHelm ChartかLinuxパッケージの複数台構成を検討します。
担当者1人の兼務や8GB未満のサーバーならオンプレ構築を見送る
次のどれかに当てはまる場合、オンプレ構築は見送ってGitLab.comを使います。
- 毎月の版上げと緊急パッチを当てる担当者が、他業務と兼務の1人しかいない
- 用意できるサーバーのメモリが8GB未満で、増設の予算もない
- バックアップの保管先を本体と別の場所に確保できない
- Gitのホスティングだけが目的で、CI/CDやIssueは使わない
いちばん多い失敗は1つ目の形です。構築した担当者が異動して更新が止まり、3か月経つとセキュリティ修正も届かない版で動き続けることになります。最後の項目に当てはまるなら、GitBucketをDockerで構築する手順のような軽いGitサーバーで十分です。GitHubと比べたい場合はGitHubとGitLabの違いとセルフホスト比較が判断材料になります。閉域網の要件があり、構築と毎月の保守を社内で抱えきれない場合は、一創のDevOps・CI/CD導入支援のように、GitLabとRunnerの構築から更新の運用までを外部に任せる形も選べます。
よくある質問
GitLabをオンプレのDockerで構築する際によく出る質問に、2026年11月12日時点の公式情報をもとに回答します。
GitLabのDockerイメージはCEとEEのどちらを使えばよいですか?
将来有料プランを使う可能性があるならEE(gitlab/gitlab-ee:<version>-ee.0)を選びます。EEはライセンス未登録ならFreeの機能で動き、CEからEEへ移るより手間がかかりません。社内規程でMITライセンスのソフトウェアしか入れられない場合はCEにします。どちらもタグの形式は同じで、docker-compose.ymlのイメージ名を変えるだけです。
Docker版GitLabの初期rootパスワードはどこにありますか?
コンテナ内の/etc/gitlab/initial_root_passwordに書かれています。sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_passwordで表示できます。このファイルは24時間経過後の最初のコンテナ再起動で自動的に消えるため、ログインしたらすぐにrootのパスワードを変更してください。
GitLabのSSHポートを22番以外にしても大丈夫ですか?
問題ありません。docker-compose.ymlのportsで'2222:22'のようにホスト側の番号を変え、GITLAB_OMNIBUS_CONFIGにgitlab_rails['gitlab_shell_ssh_port'] = 2222を書きます。両方が揃っていない場合、画面に表示されるクローン用URLのポートと実際に待ち受けるポートは不一致です。利用者のクローンURLはssh://git@ホスト名:2222/グループ/プロジェクト.gitの形になります。
バックアップから別のサーバーへGitLabを移行できますか?
別のサーバーへの移行は可能です。移行先で同じ版・同じエディションのイメージを起動し、移行元のgitlab-secrets.jsonを設定ディレクトリへコピーしてからgitlab-backup restoreを実行します。secretsを移さずに復元した場合に起こるのは、二要素認証を有効にした利用者のログイン不能やRunnerの接続不能です。DNSの切り替えは復元と点検が終わってから行います。
Docker版GitLabはどのくらいの頻度で更新すればよいですか?
マイナー版が毎月出るので、月1回の定期更新を基本にします。セキュリティ修正が届くのは直近3つのマイナー版だけのため、3か月以上止めると脆弱性の修正版を当てられなくなります。加えて、深刻度の高い脆弱性に対する臨時のパッチリリースが出た場合は、定期更新を待たずに当てる判断が必要です。
関連記事
- GitLabとは:構成要素・CEとEEの違い・3つの提供形態とDockerで試す手順【2026年11月】:構成要素の役割と、起動後に状態を確かめるコマンドを確認できます
- GitLab Runnerとは:executorの選び方と登録手順・config.tomlの設定例【2026年11月】:オンプレGitLabでCIジョブを動かすRunnerを用意するときに読みます
- GitLabの使い方:プロジェクト作成からIssue・MR・CI/CDまでの手順【2026年10月】:構築後に利用者へ案内する最初の操作手順です
- GitLab脆弱性の対応手順:KEV掲載のCVE-2026-97229と修正版19.5.3/19.4.5の判断基準【2026年11月】:緊急パッチが出たときの適用判断に使えます
- GitHubとGitLabの違い|ActionsとGitLab CIの対応表・料金・セルフホスト比較:オンプレのGitLabとGitHubのどちらにするかを比べられます