GitLabのOmnibusEdition(?)ではデフォルトでnginxがバンドルされており、特に設定しなければそのnginxが自動で使用されます。
私ね。これ、知りませんでした。バンドルされているのは知っていたのですが設定で有効にするものだと思っていました。まさかデフォルトで使用されるようになっているとは…。なんてお節介だ…。

環境


  • GitLab Omnibus 10.6.0 (Dockerを使用)
  • nginx 1.12.2
上記でやってます。今回GitLabはDockerを使っていますが直接インストールした場合でも基本は変わらないはずです。

構成


次のような構成にします。
  • GitLabのバンドルnginxは無効にする
  • nginxのバーチャルホストで指定したドメインへのアクセスをGitLabに振り分ける
  • nginxとGitLabはunixソケット通信する
unicorn(GitLabが使用しているアプリサーバ)に振り分ける方法も試してみたのですが、エラーが出たのとあまり時間がとれなかったためソケット通信でやりました。ちゃんとやればunicornのポートに振り分けることもできると思います。

GitLabの設定


基本的に下記のドキュメントの「Using a non-bundled web-server」の項目を参考にしながらやります。
NGINX settings
以下はすべて設定ファイルgitlab.rbで行います。設定ファイル内で該当する箇所を探して変更します。また、ドメインはご自身のものに置き換えてください。

外部URL設定

external_urlにドメインを設定します。
1
external_url 'https://gitlab.example.com'

外部nginx設定

GitLabにバンドルされているnginxの設定を無効にします。
1
nginx['enable'] = false
今回使用するnginx(GitLabにバンドルされていないもの)のユーザを指定します。これはwww-dataだったりする場合もあるので、使ってるnginxで確認してください。
1
2
web_server['external_users'] = ['nginx']
web_server['username'] = 'nginx'

信頼できるプロキシ設定

同一ネットワークであれば設定は不要なのですが、今回のようにDockerで動かしている場合などは必要なようです。Dockerの場合はデフォルトで172.17.0.0/16のネットワークなのでそれを指定します。
1
gitlab_rails['trusted_proxies'] = ['172.17.0.0/16']

設定反映

GitLab側はこれで完了ですのでgitlab-ctl reconfigureで設定反映させます。Dokcerの場合はコンテナ再起動でも構いません。

nginx


nginxですがこちらの公式のサンプルを参考にしました。だいたい下記のような感じになるのではないかと思います。暗号化のところはあんまり詳しくないので要件に合わせて設定してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
upstream gitlab-workhorse {
  # ソケットファイルの場所を指定
  server unix:/var/opt/gitlab/data/gitlab-workhorse/socket fail_timeout=0;
}

# httpの場合はhttpsにリダイレクトさせる
server {
    listen       80;
    server_name  gitlab.example.com;
    return       301 https://$host$request_uri;
}

server {
    listen                        0.0.0.0:443 ssl http2;
    listen                        [::]:443;
    server_name                   gitlab.example.com;
    ssl                           on;
    ssl_certificate               ${ssl.pem};
    ssl_certificate_key           ${ssl.key};
    ssl_protocols                 TLSv1.1 TLSv1.2;
    ssl_ciphers                   'ECDH !aNULL !eNULL !SSLv2 !SSLv3';
    ssl_prefer_server_ciphers     on;

    access_log /var/log/nginx/gitlab_access.log;
    error_log /var/log/nginx/gitlab_error.log;

    location / {
        proxy_set_header    Host                $http_host;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_set_header    X-Forwarded-Ssl     on;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header    X-Forwarded-Proto   $scheme;
        proxy_set_header    X-CSRF-Token        $http_x_csrf_token;
        proxy_redirect      off;
        proxy_set_header    X-Frame-Options     SAMEORIGIN;
        proxy_pass          http://gitlab-workhorse;
    }
}

ソケットのパーミッション

前述のGitLabのドキュメントにも記載されているのですが、ソケットとそのディレクトリの所有者がnginxでないとパーミッションエラーで接続できない(502 Bad Gateway)になります。
また、Dockerの場合のみの問題かもしれませんが、所有者がコンテナの起動毎にもとに戻ってしまうんですね。困った…。仕方ないので、起動後に所有者を変更するスクリプトを書きました。
1
2
3
4
5
6
#!/bin/sh

docker-compose up -d
sleep 120
chown nginx:nginx /ソケットのディレクトリ
chown nginx:nginx /ソケットのディレクトリ/socket
docker-compose upの後にGitLabが起動完了しそうな時間だけ待って、所有者を変更しているだけです。

ダメな場合は?


nginxのエラーログをみながら、nginx側の問題なのかGitLab側の問題なのか切り分けて少しづつ設定を変えて確認していきます。