Docker で実行されている GitLab Pages はコンテナ外からアクセスできません

Docker で実行されている GitLab Pages はコンテナ外からアクセスできません

DockerでGitLabインスタンスを実行しています。GitLabは正常に動作しますが、アクセスできませんGitLab ページ

セットアップ

概要

           +------------+
Request+-->+ Cloudflare |
           +-----+------+
                 |
                 v       +---------+
               Nginx+--->+Docker   |
                         |  +------+
                         |  |GitLab|
                         +---------+

問題は、Nginx がリクエストを GitLab Pages サーバーに渡すことができないことです (GitLab 自体は機能していることに注意してください)。
Nginx エラー ログ エントリ

[error] 14932#14932: *30505 connect() failed (111: Connection refused) while connecting to upstream, [...]

ドッカー

image: gitlab/gitlab-ce
version: 13.7.1 (latest)
ip: 172.17.0.7 (dynamic)
published ports:
    172.17.0.1:8080 -> 80
    172.17.0.1:8090 -> 8090

エンギンクス

ページのサーバーエントリ

server {
        listen 80 default_server;
        listen 443 default_server;
        server_name _;
        
        location / {
                proxy_pass      http://172.17.0.1:8090;
        }
}

ギットラボ

grep -v '^#|^$' gitlab.rb1

nginx['listen_port'] = 80
nginx['listen_https'] = false
pages_external_url "http://pages.example.com/"
gitlab_pages['enable'] = true
gitlab_pages['external_http'] = []
gitlab_pages['listen_proxy'] = "localhost:8090"
gitlab_pages['inplace_chroot'] = true
gitlab_pages['metrics_address'] = ":9235"
pages_nginx['enable'] = true
pages_nginx['listen_https'] = false
pages_nginx['redirect_http_to_https'] = false

pages_external_urlまた、 と のみを定義する絶対最小限の構成でも試しましたgitlab_pages['enable']

問題の追跡

  1. pages.example.com へのリクエストが CF からの 502 (Bad Gateway) で失敗しました
  2. Nginxログをチェックしたところ、上記のログエントリが見つかりました
  3. ホストからコンテナに複数のリクエストを送信しました
    1. # curl 172.17.0.1:8090 -> curl: (7) Failed to connect to 172.17.0.1 port 8090: Connection refused
    2. # curl 172.17.0.7:8090 -> curl: (7) Failed to connect to 172.17.0.7 port 8090: Connection refused
  4. コンテナからリクエストを送信しました
    # curl localhost:8090 -> 404 error page

このことから、8090への着信トラフィックが何かによってブロックされていると推測します。(GitLab ページ)、しかし80への要求(GitLab)正常に完了しました。この問題について Google で数日間検索しましたが、何も見つかりませんでした。


1切り捨て。SMTP、LDAP、omniauth 設定が削除されました

答え1

何時間も間違ったことを調べ続けた後、ようやく問題の原因を見つけました (これについては後ほど詳しく説明します)。

要約

すべてのインターフェースで listen するように値を変更する必要があったgitlab_pages['listen_proxy']ため、次のようになります。

gitlab_pages['listen_proxy'] = "0.0.0.0:8090"

詳細

私はGitLab Pagesに関連するキーワードでこの問題を検索していましたが、今、もっと一般的な問題で、GitLab Pagesに関連しないものだったらどうだろうと、枠にとらわれずに考える必要があるかもしれないと思いました。最初のGoogle検索の後、私は素晴らしい記事これについて。

ポート 8090 で何もリッスンしていなかったため、「接続が拒否されました」というメッセージlocalhostが表示されました。これは、 がループバック アドレスを参照しているためです127.0.0.1。ただし、公開されたポートはコンテナーの IP に転送されます。私の場合、質問を書いている時点では であった動的 IP に転送されます。したがって、解決策は、 を IP アドレスとして172.17.0.7使用して可能なすべてのインターフェイスでリッスンすることです。0.0.0.0

問題と解決策を視覚化する2つの図

(図は前述の記事から引用したものですが、質問に合うように若干修正し、force-darkmode 使用時の読みやすさを向上させるためにテキストのみにしました)
使用する場合localhost:8090

   Request      +--------------------------------------+
      +         | Default network namespace            |
      |         |                                      |
      |         |               +-------+              |
      v         |        +----->+ Nginx +------+       |
+-----+------+  |        |      +-------+      |       |
| Cloudflare |  |        |                     |       |
+-----+------+  |        |                     v       |
      |         +--------+-----------+-+-------+-------+
      |         | Physical interface | | Docker bridge |
      +-------->+ 10.0.0.1           | | 172.17.0.1    |
                +--------------------+ +-------+-------+
                                               |
                                               |
                                               v
                                       +-------+-------+
                                       | Docker bridge |
                                       | 172.17.0.7    |
                 +-------+-----------+-+---------------+
                 |       | Loopback  |                 |
                 |       | 127.0.0.1 |                 |
                 |       +-----+-----+                 |
                 |             |                       |
                 |             |      +--------------+ |
                 |             +----->+ Pages server | |
                 |                    +--------------+ |
                 |GitLab's Network namespace           |
                 +-------------------------------------+

次を使用して、すべてのインターフェースでリッスンします0.0.0.0:8090

   Request      +--------------------------------------+
      +         | Default network namespace            |
      |         |                                      |
      |         |               +-------+              |
      v         |        +----->+ Nginx +------+       |
+-----+------+  |        |      +-------+      |       |
| Cloudflare |  |        |                     |       |
+-----+------+  |        |                     v       |
      |         +--------+-----------+-+-------+-------+
      |         | Physical interface | | Docker bridge |
      +-------->+ 10.0.0.1           | | 172.17.0.1    |
                +--------------------+ +-------+-------+
                                               |
                                               |
                                               v
                                       +-------+-------+
                                       | Docker bridge |
                                       | 172.17.0.7    |
                 +-------+-----------+-+-------+-------+
                 |       | Loopback  |         |       |
                 |       | 127.0.0.1 |         |       |
                 |       +-----+-----+         |       |
                 |             |               v       |
                 |             |      +--------+-----+ |
                 |             +----->+ Pages server | |
                 |                    +--------------+ |
                 |GitLab's Network namespace           |
                 +-------------------------------------+

答え2

Gitlab 16.xxの最新設定

GITLAB_OMNIBUS_CONFIG: |
        ### Web interace settings
        external_url "https://gitlab.domain.org"
        nginx['listen_port'] = 80
        nginx['listen_https'] = false

        ### Pages
        gitlab_pages['enable'] = true
        pages_external_url "https://pages.domain.org"
        pages_nginx['ssl'] = false
        pages_nginx['listen_https'] = false
        gitlab_pages['listen_proxy'] = '0.0.0.0:8090'
        gitlab_pages['internal_gitlab_server'] = 'http://localhost:8080'

これは、リバース プロキシ (nginx/traefik/その他) の背後にある 1 つの Docker コンテナの構成です。ロード バランサーで https (TLS) を終了し、トラフィックを HTTP ポートにプロキシする場合: 80 - gitlab、8090 - pages。

関連情報