Painless manual upgrade from within China
steps
- create SOCKS5 proxy outside of China
- set up and configure proxy connection on CN server
- create a template for simpler editing
- add git proxy settings to template
- include template in
app.yml
- rebuild app
1 - remote SOCKS5
For the ease of use (and their friendly pricing) I recommend setting up a Digital Ocean server in e.g. Singapore. Just use a standard Ubuntu server, go through all the basic security requirements configurations (SSH keypairs, UFW, et cetera), then install Shadowsocks:
on remote machine
$ sudo apt install shadowsocks-libev
Configure the proxy settings:
$ cd /etc/shadowsocks-libev
# I like to keep the original files
$ sudo cp config.json orig.config.json
$ sudo nano config.json
Pay close attention to timeout and method:
{
"server":"123.123.123.123", # remote server IP
"server_port":8400, # up to you
"local_port":1080,
"password":"Swordfish",
"timeout":600, # <= essential!
"method":"chacha20-ietf-poly1305"
}
Make sure to double-check all the settings in the systemd
configuration (/lib/systemd/system/shadowsocks-libev-local@.service
). Enable the shadowsocks-libev-local@.service
, reboot, check for running service.
2 - set up the proxy connection on the CN server
on Discourse machine
$ sudo apt install shadowsocks-libev
If you are on Aliyun, search for the Firewall settings in their weird console and check for the respective port settings.
You do not need to fuzz around with the systemd
settings on the client machine, but keep separate config files for docker and regular use, as you might want to use the SOCKS5 proxy outside the context of docker, thus you would want to use 127.0.0.1
instead of the Docker accessible network addresses.
$ cd /etc/shadowsocks-libev
$ sudo cp config.json local.json
$ sudo cp config.json docker.json
adapt the config to something similar like this
$ sudo nano local.json
{
"server":["123.123.123.123"], # the remote machine's IP
"mode":"tcp_and_udp", # this annotation is different due to different shadowsocks-libev versions in my set up
"server_port":8400,
"local_address":"127.0.0.1",
"local_port":1080,
"password":"Swordfish",
"timeout":600, # <= make sure about that
"method":"chacha20-ietf-poly1305"
}
For the sake of convenience, let us add an alias to our .bashrc
:
$ nano ~/.bashrc
# paste
alias dockershadow='ss-local -c /etc/shadowsocks-libev/local.json'
adapt the other config to let Docker go through the host machine’s network
$ sudo nano docker.json
{
"server":["123.123.123.123"],
"mode":"tcp_and_udp",
"server_port":8400,
"local_address":"172.17.0.1",
"local_port":1080,
"password":"Swordfish",
"timeout":600,
"method":"chacha20-ietf-poly1305"
}
set the alias for using the Docker specific config:
alias dockershadow='ss-local -c /etc/shadowsocks-libev/docker.json'
3 & 4 - create a template for keeping your app.yml tidy
This is absolutely optional and depends on your taste; I prefer keeping the app.yml
readable and short, and instead maintain components elsewhere. Give it any name according to your taste, I chose web.git.template.yml
.
$ nano templates/web.git.template.yml
# paste:
hooks:
before_code:
- exec:
cmd:
- git config --global http.proxy socks5://172.17.0.1:1080
- git config --global https.proxy socks5://172.17.0.1:1080
- git config --global https.sslVerify = false
# optional
after_code:
- exec:
cmd:
- git config --global --unset http.proxy
- git config --global --unset https.proxy
- git config --global --unset https.sslVerify
I have tested it with the hook after_web
, but that didn’t do the trick.
5 - adapt the app.yml
Call the template in your app.yml
:
$ cd /<discourse dir>
$ sudo nano containers/app.yml
templates:
- "templates/web.template.yml"
- "templates/web.china.template.yml"
- "templates/web.ratelimited.template.yml"
- "templates/web.socketed.template.yml"
- "templates/web.git.template.yml"
Your template section most likely looks different, just make sure to include web.china
and the web.git-blabla
(or whatever you named it) templates.
Do not expose 1080:1080
in your app.yml
!
6 - rebuilding
Before rebuilding verify that your proxy settings are workable when cloning with git.
$ git config --global http.proxy socks5://172.17.0.1:1080
$ git config --global https.proxy socks5://172.17.0.1:1080
$ git config --global https.sslVerify = false
This of course adds the proxy flags to your user’s .gitconfig
in the home directory, so pay attention to remove this after testing.
Select a random large repo on Github with a ton of files and check your cloning speed. If your configuration is correct, you should be able to clone with ~12-15 mb/s, depending on your Aliyun setup. If your connection speed slowly crawls up from 200 kb/s to about 10 mb/s, then your efforts were not successful.
finally rebuild:
$ cd /<discourse directory>
# run the proxy by using the alias we have set before
$ dockershadow
$ ./launcher rebuild app
The rebuild process will fail often, so you need patience (and possibly Baijiu). The fewer plugins you have set in your app.yml
, the more likely it is that your rebuild will succeed.
7 - remarks
I still consider this as a workaround, not a production ready procedure, so maybe somebody has an idea of how to mirror the GitHub repo in China, to make this less painful. And as we all know, the intransparent mechanisms inside the GFW keep changing.
Of course a SOCKS5 proxy is just one of many options, but Iike to have multi-use solutions at hand.
If anybody has an idea how to make this workaround production-ready, I appreciate your input. Discourse is fantastic software, but I assume one of the reasons for not being widely used in China is the cumbersome installation and maintenance processes. Trying to upgrade via GUI gave me a 100% failure rate within the last year, no matter which timeout settings I had configured in my nGinx reverse proxy.
Chinese translation will follow