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?

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.)

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.

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).

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

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

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?

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

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

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.

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).