Páginas do GitLab em execução no Docker inacessíveis de fora do contêiner

Páginas do GitLab em execução no Docker inacessíveis de fora do contêiner

Eu tenho uma instância do GitLab em execução no docker. GitLab funciona bem, mas não consigo acessarPáginas do GitLab.

A configuração

Visão geral

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

O problema é que o Nginx não consegue passar a solicitação para o servidor GitLab Pages (observe que o GitLab funciona sozinho).
Entrada de log de erros do Nginx

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

Docker

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

Nginx

Entrada de servidor para páginas

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

GitLab

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

Também tentei com a configuração mínima absoluta, definindo apenas pages_external_urle gitlab_pages['enable'].

Rastreando o problema

  1. A solicitação para pages.example.com falhou com 502 (Bad Gateway) do CF
  2. Log Nginx verificado, encontrou a entrada de log mencionada acima
  3. Fez várias solicitações do host para o contêiner
    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. Fez uma solicitação do contêiner
    # curl localhost:8090 -> 404 error page

A partir disso, presumo que algo esteja bloqueando o tráfego de entrada para 8090(Páginas do GitHub), mas solicita para 80(GitLab)são concluídos com sucesso. Passei alguns dias pesquisando esse problema no Google, mas não consegui encontrar nada.


1 Truncado; Configurações SMTP, LDAP e omniauth removidas

Responder1

Acabei de encontrar a causa do meu problema depois de muitas horas pesquisando a coisa errada (mas falaremos mais sobre isso mais tarde).

DR

Tive que alterar o gitlab_pages['listen_proxy']valor para escutar em todas as interfaces, então ficou assim:

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

Detalhado

Eu estava pesquisando esse problema com palavras-chave relacionadas às páginas do gitlab e agora pensei que talvez precisasse pensar fora da caixa, e se for um problema mais geral e nem mesmo relacionado às páginas do GitLab. Depois da primeira pesquisa no Google encontrei umbom artigosobre isso.

Recebi a mensagem "conexão recusada" porque nada estava escutando na porta 8090, pois localhostse refere ao endereço de loopback, ou seja 127.0.0.1, mas as portas expostas são encaminhadas para o IP do contêiner, no meu caso para um IP dinâmico que ao escrever a pergunta era 172.17.0.7. Portanto a solução é escutar em todas as interfaces possíveis usando 0.0.0.0como endereço IP.

Duas figuras que visualizam o problema e a solução

(Figuras do artigo mencionado, mas ligeiramente modificadas para corresponder melhor à pergunta e torná-lo texto apenas para melhorar a legibilidade ao usar o modo force-dark)
Ao usar 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           |
                 +-------------------------------------+

Ouvindo em todas as interfaces, usando 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           |
                 +-------------------------------------+

Responder2

Minha configuração mais recente para 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'

Esta é a configuração para 1 contêiner docker, que fica atrás de um proxy reverso (nginx/traefik/whatever). Se você encerrar https(TLS) no balanceador de carga e ele fizer proxy do tráfego para portas HTTP: 80 - gitlab, 8090 - páginas.

informação relacionada