Como reconstruir o aplicativo usando a rede do host em vez da rede docker?

Olá,

Às vezes, ao realizar atualizações via a interface web, o Discourse pede para executar:

cd /var/discourse
git pull
./launcher rebuild app

Como o processo de rebuild se conecta várias vezes ao GitHub e o GitHub é parcialmente bloqueado na China, onde meu servidor está hospedado, preciso configurar um proxy HTTP/HTTPS para acessar o GitHub com mais eficiência. Aqui está uma comparação entre acessar o YouTube sem proxy e com proxy:

root@iosre:/var/discourse# wget https://youtube.com
--2021-06-10 23:55:05--  https://youtube.com/
Resolving youtube.com (youtube.com)... 66.220.152.17, 2001::3d6f:fadc
Connecting to youtube.com (youtube.com)|66.220.152.17|:443... ^C
root@iosre:/var/discourse# export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7891
root@iosre:/var/discourse# wget https://youtube.com
--2021-06-10 23:56:12--  https://youtube.com/
Connecting to 127.0.0.1:7890... connected.
Proxy request sent, awaiting response... 301 Moved Permanently
Location: https://www.youtube.com/ [following]
--2021-06-10 23:56:13--  https://www.youtube.com/
Connecting to 127.0.0.1:7890... connected.
Proxy request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: 'index.html'

index.html [  <=>  ] 510.58K   813KB/s    in 0.6s    

2021-06-10 23:56:14 (813 KB/s) - 'index.html' saved [522830]

No entanto, quando executo ./launcher rebuild image, o script entra no aplicativo e realiza todas as operações dentro do Docker, onde o ambiente de rede é diferente do do host com proxy, e não consigo acessar o YouTube. Por isso, o rebuild falha na maioria das vezes.

root@iosre:/var/discourse# ./launcher enter app
root@iosre-app:/var/www/discourse# wget https://youtube.com
--2021-06-10 15:59:57--  https://youtube.com/
Resolving youtube.com (youtube.com)... 69.171.248.128, 2001::d238:33c1
Connecting to youtube.com (youtube.com)|69.171.248.128|:443... ^C
root@iosre-app:/var/www/discourse# export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7891
root@iosre-app:/var/www/discourse# wget https://youtube.com
--2021-06-10 16:00:10--  https://youtube.com/
Connecting to 127.0.0.1:7890... failed: Connection refused.

Minha pergunta é: o que posso fazer para utilizar o proxy do host dentro do Docker, especialmente ao executar ./launcher rebuild app?

2 curtidas

Talvez veja Replace rubygems.org with taobao mirror to resolve network error in China

Também existe um modelo para a China que você pode incluir. Você pode vê-lo na pasta de modelos. Não tenho certeza do que ele faz.

(Isso não é uma ótima resposta, mas já se passaram dois dias e você ainda não tem nenhuma.)

4 curtidas

Obrigado, Jay! O template da China espelha o rubygems.org com o gems.ruby-china.com, que é hospedado pelo taobao/alibaba.

Inspirado por essa ideia, vou tentar espelhar o github.com com um doméstico, de preferência hospedado também pela Alibaba.

3 curtidas

Oi @snakeninny, se entendi a pergunta corretamente, você pode precisar de algo assim:

/var/discourse/launcher rebuild app --docker-args --net=host --skip-mac-address

Neste caso, você provavelmente precisará modificar o app.yml, na seção expose (basta verificar netstat -ltupen para encontrar a porta de escuta real do container).

2 curtidas

Obrigado, Ivan! Fiz isso, mas não modifiquei o app.yml para expor a seção. Como faço isso?

1 curtida

Abra o arquivo app.yml do containers com um editor de texto e procure por “expose”.

1 curtida

Vejo isso na seção expose do app.yml:

expose:
  - "30080:80"   # encaminha a porta 80 do host para a porta 80 do contêiner (http)
  - "2222:22" # encaminha a porta 2222 do host para a porta 22 do contêiner (ssh)

Preciso encaminhar a porta 443 do host (https) para alguma porta do contêiner? Para qual porta do contêiner devo encaminhar?

1 curtida

Isso não funcionava antes? Espero que seu proxy reverso esteja lidando com coisas de HTTPS.

1 curtida

Não, não foi. Como já descrevi, consigo acessar o YouTube no host, mas não no Docker.

1 curtida

Sua configuração é um pouco complicada demais para eu adivinhar qual é o seu problema. Recomendo configurar tudo sem um proxy reverso primeiro. Depois, siga Como configurar o Discourse em um servidor com sites Apache existentes ou Executar outros sites na mesma máquina que o Discourse.

2 curtidas

Olá @snakeninny, desculpe pelo atraso.

Seguindo sua configuração 30080:80 na seção de exposição, você só precisa configurar as requisições de proxy no seu Nginx/Apache/etc.

Por exemplo, minha configuração para Nginx (eu uso 2080 em vez de 30080):

/etc/nginx/sites-available/00-default-ssl.conf

server {
...

        location / {
                # ISSO É USADO COM NGINX QUANDO O DOCKER É EXECUTADO NORMALMENTE (MODO BRIDGE)
                proxy_pass      http://example.com:2080/;
                
                # ESSAS 2 LINHAS SÃO USADAS CASO A REDE DOCKER ESTEJA NO MODO HOST (--net=host)
                #proxy_pass      http://example.com:3000/;
                #proxy_redirect  http://example.com:2080/ https://example.com;

                proxy_read_timeout 90;
                proxy_http_version 1.1;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;

                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Server $host;

                error_page 502 =502 /errorpages/discourse_offline.html;
                proxy_intercept_errors on;

    # VOCÊ PODE EXCLUIR REQUISIÇÕES DE CERTOS IPs DO LOG DE ACESSO
    if ( $remote_addr = "x.x.x.x" )
    {
        access_log off;
    }
        }

location /errorpages/ {
    alias /var/www/errorpages/;
}
}

Quando você executar seu contêiner no modo host (--net=host), você deve considerar alterar suas configurações de proxy para usar a porta 3000 com redirecionamento (provavelmente https, como no exemplo acima).

2 curtidas