The fun adventure of running VSCode locally with purely native functionalities.
If you want just the working solution, then jump to the Solution section.
Why?
I like to code from my couch. But I don’t have a laptop only iPad.
How? (Requirements)
- it has to support iPad, - ssh remote plugin is not an option, only browser based solution is possible;
- use only Microsoft Visual Studio Code binary and avoid 3rd party repositories;
- run it in the local network (so tunnel is not an option since it is proxied over the Internet);
- it would be nice if connection would be secure.
Architecture
We are considering 2 machines in the local network:
- linux server - running vscode server;
- iPad - client of vscode server.
The (painful) story to the success
Command
We are starting with simple knowledge: code supports running itself as http server with command:
code serve-web --host 0.0.0.0 --port 1234 --connection-token super-secret
It appears that we can re-configure everything we want, to achieve the goal:
- host on which server is listening (default: localhost),
- port to something static (default: random),
- secret (token) which is required to connect and its passed as GET param (default: random).
We have everything what we needed, so post can be ended here, right?
Problem 1: Unathorized Client
When we try to launch the above command and open our code instance from the iPad we can notice the popup with error:
An unexpected error occurred that requires a reload of this page.
The workbench failed to connect to the server (Error: Connection error: Unauthorized client refused)
According to the github issue one of the components will fail for non-localhost server hosting without tls.
OK, so we can run it over localhost, but behind https proxy like nginx. Nothing simpler, right?
Problem 2: Find the working nginx config
Code runs a lot of things over websockets and here is a big issue, because we need to configure the proxy in the correct way. Here I encountered 3 major subproblems.
Error: WebSocket close with status code 1006 behind nginx proxy
It will show-up for the configurations where proxy is with websocket support disabled as described for example here.
Error: Extension file not found when code-server serve-local
Something executes, but there are some problems with interactions and server shows errors about missing files as in this case. This is mostly related to websockets and invalid Host header.
No error, but still it doesn’t work
And finally - my favourite - no errors, but when you try to open folder from the browser it just doesn’t work - no errors at all.
Solution
It took me a long hours to find the working combination of settings. Below you can find complete, working example.
1. Generete SSL certs
# as root
mkdir /etc/ssl/vscode # or whenever you want to put it
cd !$
openssl req -new -key code.key -out code.csr -subj "/C=US/ST=State/L=City/O=HOST/CN=YOUR_HOST"
openssl x509 -req -days 365 -in code.csr -signkey code.key -out code.crt
2. NGINX Config
# in case you don't have it, instructions for ubuntu
sudo apt install nginx
sudo systemctl enable nginx
sudo systemctl start nginx
Create nginx config file in: /etc/nginx/sites-available/code
:
server {
listen 443 ssl;
server_name hangar.local;
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/cert.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://127.0.0.1:3291/;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_connect_timeout 60;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
add_header X-Cache $upstream_cache_status;
}
}
In above config please replace the paths to your certs. I will be also using port 3291
for hosting code server over localhost, feel free to replace it if you want.
Now, enable it:
sudo ln -s /etc/nginx/sites-available/code /etc/nginx/sites-enabled/code
sudo systemctl restart nginx
3. Start code server
code serve-web --port 3291 --connection-token YOURSECRET
Protip, you can also create the alias from it to run it easier in your .bashrc
or .zshrc
:
alias codeserver='code serve-web --port 3291 --connection-token YOURSECRET'
4. Open it in the browser
Go to the https://YOUR_HOSTNAME/?tkn=YOURSECRET
and wait for a moment until vsode will launch.
I recommend to add above url as bookmark to simplify the process of launching Code Server from the browser.
Finito!