I use VSCode Remote-SSH to connect to VPS to code, so that I can use the same environment in a new PC. However, a problem arises when I only have a tablet on hand, as there is no desktop version of VSCode available for tablets. To bridge this gap, I turned to the code-server project, which provides a browser-based VSCode client. Naturally, my next step was to sync my configurations between Remote-SSH and code-server.
Installing VSCode Remote-SSH
Install Remote-SSH extension in local VSCode and click the blue button in the bottom left corner to install the VSCode server on your VPS.
Installing Code-server
To make syncing the environments easier, I chose a native installation over Docker. Simply run the official installation script.
curl -fsSL https://code-server.dev/install.sh | shLinking Extensions and Configurations
mkdir -p ~/.local/share/code-server/User/
# link extensions
ln -s ~/.vscode-server/extensions ~/.local/share/code-server/extensions
# link configurations
ln -s ~/.vscode-server/data/Machine/settings.json ~/.local/share/code-server/User/settings.json
# link snippets
ln -s ~/.vscode-server/data/User/snippets ~/.local/share/code-server/User/snippetsIn practice, I found that the settings.json formats between the two are slightly incompatible. However, since I rarely change these configurations, I just ignored this minor issue.
Using the Microsoft Official Marketplace
First, edit environment variables:
sudo systemctl edit code-server@$USERInsert the following snippet inside the specified block (as indicated by the systemd comments):
[Service]
Environment='EXTENSIONS_GALLERY={"serviceUrl":"https://marketplace.visualstudio.com/_apis/public/gallery","itemUrl":"https://marketplace.visualstudio.com/items","resourceUrlTemplate":"https://%%7Bpublisher%%7D.vscode-unpkg.net/%%7Bpublisher%%7D/%%7Bname%%7D/%%7Bversion%%7D/%%7Bpath%%7D","controlUrl":"","recommendationsUrl":""}'Restart the service:
sudo systemctl daemon-reload
sudo systemctl restart code-server@$USERConfiguring Code-server
Open the configuration file:
vim ~/.config/code-server/config.yamlEdit port and passsword. For security reasons, I bound the address to 127.0.0.1 so it isn’t exposed directly to the public web. I will handle external access using an Nginx reverse proxy later.
bind-addr: 127.0.0.1:8080
auth: password
password: "YourPassword"
cert: falseManually start the service:
sudo systemctl enable --now code-server@$USER
sudo systemctl status code-server@$USERSetting Up the Nginx Reverse Proxy
I’m using a Cloudflare origin certificate, stored in /etc/nginx/ssl/example_com.
Edit Nginx’s configuration:
sudo vim /etc/nginx/conf.d/codeserver.confserver {
listen 80;
server_name code.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name code.example.com;
ssl_certificate /etc/nginx/ssl/example_com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/example_com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
proxy_connect_timeout 3600s;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
access_log /var/log/nginx/codeserver.access.log;
error_log /var/log/nginx/codeserver.error.log;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header CF-Connecting-IP $http_cf_connecting_ip;
proxy_set_header X-Real-IP $http_cf_connecting_ip;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Verify the syntax:
sudo nginx -tReload Nginx:
sudo systemctl reload nginx