How do I rebuild app using the host network rather than the docker network?

Hi,

Sometimes when I perform upgrades via the web UI, discourse tells me to run

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

Since the rebuild process connects to github several times and github is half-blocked in China, where my server is hosted, I have to setup http/https proxy to better access github. Here is a comparison between visiting youtube w/o proxy and w/ 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]

However when I run ./launcher rebuild image, the script will enter the app and perform all operations inside the docker, where the network environment is different from the proxied host, and I’m not able to access youtube, so rebuild will fail most of the time.

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.

My question is, what can I do to make use of the host proxy inside the docker, especially in ./launcher rebuild app?

2 Likes

Maybe see Replace rubygems.org with taobao mirror to resolve network error in China

There’s also a China template that you can include. You can see it in the templates folder. I’m not quite sure what it does.

(This isn’t a great answer, but it’s been two days and you don’t have any yet.)

4 Likes

Thanks Jay! The China template mirrors rubygems.org with gems.ruby-china.com, which is hosted by taobao/alibaba.

Inspired by that idea, I will try to mirror github.com with a domestic one, hopefully hosted by alibaba too.

3 Likes

Hi @snakeninny if I understood the question right, you may need something like this:

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

In this case you probably need to modify app.yml, expose section (just check netstat -ltupen to find actual container listening port).

2 Likes

Thanks Ivan! I have done this but haven’t modified app.yml to expose section. How do I do that?

1 Like

Open containers app.yml with a text editor and look for “expose”.

1 Like

I can see this in app.yml expose section:

expose:
  - "30080:80"   # fwd host port 80   to container port 80 (http)
  - "2222:22" # fwd host port 2222 to container port 22 (ssh)

Do I need to forward host port 443 (https) to container port? Which container port should I forward to?

1 Like

Didn’t this work before? I expect that your reverse proxy is doing https stuff.

1 Like

No it didn’t. As I have described, I can access youtube in the host, but not in the docker

1 Like

Your setup is a bit too complicated to guess what your issue is. I recommend getting things set up without a reverse proxy first. And then set How to set up Discourse on a server with existing Apache sites or Running other websites on the same machine as Discourse

2 Likes

Hi @snakeninny , sorry for delay.

Following your setting 30080:80 in expose section, you just need to set up proxy requests on your Nginx/Apache/etc.

For example, my setting for Nginx (I use 2080 insteal of 30080):

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

server {
...

        location / {
                # THIS IS USED WITH NGINX WHEN DOCKER IS RUN NORMALLY (BRIDGED MODE)
                proxy_pass      http://example.com:2080/;
                
                # THESE 2 LINES ARE USED IN CASE DOCKER NETWORK IS IN HOST MODE (--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;

    # YOU MAY EXCLUDE REQUESTS FROM CERTAIN IP FROM ACCESS LOG
    if ( $remote_addr = "x.x.x.x" )
    {
        access_log off;
    }
        }

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

When you run your container in host mode (--net=host), your should consider to switch your proxy settings to use 3000 port with redirect (probably https as in an example above).

2 Likes