Как пересобрать приложение, используя хост-сеть вместо сети Docker?

Здравствуйте,

Иногда при выполнении обновлений через веб-интерфейс Discourse предлагает выполнить следующие команды:

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

Так как процесс rebuild несколько раз обращается к GitHub, а в Китае, где расположен мой сервер, доступ к GitHub частично заблокирован, мне приходится настраивать HTTP/HTTPS-прокси для более стабильного доступа к GitHub. Ниже приведено сравнение доступа к YouTube без прокси и с прокси:

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]

Однако при запуске ./launcher rebuild image скрипт входит в контейнер приложения и выполняет все операции внутри Docker, где сетевая среда отличается от настроенной на хосте с прокси. Из-за этого доступ к YouTube становится невозможным, и процесс rebuild чаще всего завершается неудачей.

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.

Вопрос: что можно сделать, чтобы использовать прокси хоста внутри Docker, особенно при выполнении ./launcher rebuild app?

Возможно, стоит посмотреть Replace rubygems.org with taobao mirror to resolve network error in China

Также есть шаблон для Китая, который вы можете включить. Вы можете найти его в папке с шаблонами. Я не совсем уверен, что именно он делает.

(Это не идеальный ответ, но прошло уже два дня, а у вас до сих пор нет ни одного.)

Спасибо, Джей! Китайский шаблон зеркалит rubygems.org через gems.ruby-china.com, который размещён taobao/alibaba.

Вдохновившись этой идеей, я попробую создать зеркало github.com на отечественном сервере, надеюсь, тоже размещённом у Alibaba.

Привет, @snakeninny, если я правильно понял вопрос, вам может понадобиться что-то вроде этого:

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

В этом случае, вероятно, нужно изменить файл app.yml, секцию expose (просто выполните netstat -ltupen, чтобы найти реальный порт прослушивания контейнера).

Спасибо, Иван! Я выполнил это, но не изменил app.yml, чтобы открыть секцию. Как это сделать?

Откройте файл app.yml в текстовом редакторе и найдите строку “expose”.

Я вижу это в секции expose файла app.yml:

expose:
  - "30080:80"   # перенаправление порта хоста 80 на порт контейнера 80 (http)
  - "2222:22" # перенаправление порта хоста 2222 на порт контейнера 22 (ssh)

Нужно ли мне перенаправлять порт хоста 443 (https) на порт контейнера? На какой порт контейнера следует выполнять перенаправление?

Разве это не работало раньше? Я предполагаю, что ваш обратный прокси занимается обработкой HTTPS.

Нет, не получилось. Как я уже описывал, я могу заходить на YouTube с хоста, но не из Docker.

Ваша конфигурация слишком сложна, чтобы точно определить проблему. Рекомендую сначала настроить всё без обратного прокси. После этого ознакомьтесь с инструкциями: Как установить Discourse на сервере с существующими сайтами Apache или Запуск других веб-сайтов на том же компьютере, что и Discourse

Привет, @snakeninny, извините за задержку.

Согласно вашей настройке 30080:80 в разделе expose, вам нужно лишь настроить прокси-запросы в вашем Nginx/Apache и т.д.

Например, моя настройка для Nginx (я использую 2080 вместо 30080):

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

server {
...

        location / {
                # ЭТО ИСПОЛЬЗУЕТСЯ С NGINX, КОГДА DOCKER ЗАПУЩЕН ОБЫЧНЫМ СПОСОБОМ (РЕЖИМ BRIDGE)
                proxy_pass      http://example.com:2080/;
                
                # ЭТИ ДВЕ СТРОКИ ИСПОЛЬЗУЮТСЯ, ЕСЛИ СЕТЕВАЯ МОДЕЛЬ DOCKER УСТАНОВЛЕНА В РЕЖИМ 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;

    # ВЫ МОЖЕТЕ ИСКЛЮЧИТЬ ЗАПРОСЫ ОТ КОНКРЕТНОГО IP ИЗ ЖУРНАЛА ДОСТУПА
    if ( $remote_addr = "x.x.x.x" )
    {
        access_log off;
    }
        }

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

Когда вы запускаете ваш контейнер в режиме хоста (--net=host), вам следует рассмотреть возможность переключения настроек прокси на использование порта 3000 с перенаправлением (вероятно, через https, как в примере выше).