VS Code is my favorite editor for web development. The integrated terminal, the great plugin ecosystem, debugger, and excellent TypeScript support make it just perfect. Its one reason I keep coming back to developing locally. Because while I could run vim
on the terminal and work remotely, I'm just not as productive in vim
.
Of course there are other options. Cloud development is pretty great. Working on a project entirely remote on a browser is liberating. My project is always ready to be worked on, untethered from my machine. But cloud editors each have their own drawbacks. Ultimately, I want to drop into the terminal, start and stop services, and do all that I am able to do from my local machine. If only there was a way to run VS Code directly on a remote server, it would be the best of both worlds.
Well, now there is! Thanks to code-server
by coder.com
coder / code-server
VS Code in the browser
code-server
Run VS Code on any machine anywhere and access it in the browser.
Highlights
- Code on any device with a consistent development environment
- Use cloud servers to speed up tests, compilations, downloads, and more
- Preserve battery life when you're on the go; all intensive tasks run on your server
Requirements
See requirements for minimum specs, as well as instructions on how to set up a Google VM on which you can install code-server.
TL;DR: Linux machine with WebSockets enabled, 1 GB RAM, and 2 vCPUs
Getting started
There are four ways to get started:
- Using the install script, which automates most of the process. The script uses the system package manager if possible.
- Manually installing code-server
- Deploy code-server to your team with coder/coder
- Using our one-click buttons and guides to deploy code-server to a cloud provider ⚡
If you use the install script, you can preview what occurs…
Getting started
To get started, you'll need to log into your remote development server. This can be something like a Droplet from Digital Ocean, an AWS Lightsail instance, or any other cloud or internet connected server one would want to use. ssh
access is needed.
One could then log into the remote server and either run code-server in docker or just use one of their binary releases. I used the the binary distribution for my purposes
https://github.com/codercom/code-server/releases
Here is an example of how that might go
mkdir ~/code-server
wget -qO- LINK_TO_DESIRED_BINARY \
| tar xvz --strip-components=1 -C ~/code-server
The code-server
binary comes with a few options. At the time of this writing, it seems that the application had some trouble when given a relative paths on my system. So I wrote a super simple wrapper around it in bash, decided to call it code
and place that in ~/bin
which is my PATH
variable.
vim ~/bin/code
#!/usr/bin/env bash
abs=$(realpath .)
req=$1
if [[ ! $1 =~ ^\/ ]];
then
req="$abs/$1"
fi;
if [[ ! -d $req ]];
then
echo "ERROR: path does not exist"
echo "$req"
exit;
fi;
~/code-server/code-server $req --no-auth
chmod +x ~/bin/code
This script starts code-server
with the no-auth
option. The no-auth
option disables the built-in encryption functionality and the password authentication page. I do this because I would rather encrypt the traffic through a proxy server or through a SSH tunnel. I can also password protect the page using the web server that proxies connections.
Now to start the server, I simply open a project similar to how I would with VS Code directly.
code /path/to/project
This will start serving VS Code over port 8443
. There are two ways to connect to it; either through an SSH tunnel or by using a web server reverse proxy.
SSH Tunneling / Port Forwarding
You can forward a remote port from the server to your local client by using SSH. Here is how it would look to format port 8443
from the server to your local machine.
ssh -N -L 0.0.0.0:8443:localhost:8443 login@your-server \
2> /dev/null
This command won't give you the remote shell, it will just do the port forwarding. Now you can open your browser and visit http://localhost:8443
. Behold! You are now using VS Code, running on your server, from your browser!
What is pretty incredible is that you have access to the terminal as well! This is very powerful stuff--so beware!
One final piece is to proxy any other running services on unprivileged ports, like port 3000
or 8080
. One way to do this is by opening another terminal and making another connection.
ssh -N -L0.0.0.0:3000:localhost:3000 login@your-server \
2> /dev/null
Or proxy both ports at once
ssh -N \
-L 0.0.0.0:8443:localhost:8443 \
-L 0.0.0.0:3000:localhost:3000 \
login@your-server \
2> /dev/null
Web Server Reverse Proxy
Note: this option is for if you want to handle encryption and password protection yourself.
BE SURE TO ENCRYPT AND PASSWORD PROTECT PUBLIC URLS.
Correctly setting up a reverse proxy through a web server is a more involved process. I will provide only an overview of what you need to make this work.
- Make sure you have an SSL certificate. You can get one using
certbot
by Let's Encrypt. - Configure a web server to create reverse proxy between port 8443 and your desired URL. Be sure to proxy websocket traffic as well.
- Password protect access to the URL
In my case, I also want to proxy services running for development purposes, like port 3000
or 8080
.
APACHE
You'll need to ensure that the proper modules are loaded
sudo a2enmod rewrite
Then a configuration might be something that starts like this
<VirtualHost ip_address:443>
# Enable Modules
RewriteEngine On
SSLEngine On
# Configure basics
ServerName your.address
ServerAdmin whoever@your.address
# Proxy Traffic
RewriteCond %{HTTP:Upgrade} =websocket
RewriteRule /(.) ws://localhost:8443/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /(.) http://localhost:8443/$1 [P,L]
# Require Password
AuthUserFile /path/to/.htpasswd
AuthGroupFile /dev/null
AuthName "Title"
AuthType Basic
require valid-user
# Use SSL
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/yourwebsite.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourwebsite.com/privkey.pem
SSLProtocol all
SSLCipherSuite HIGH:MEDIUM
# And so on...
NGINX
I've not tried doing this for code-server
with NGINX yet. NGINX is particularly apt for this. Here are some references on where I would start:
Encrypt traffic and reverse proxy w/ websockets
https://gist.github.com/steve-ng/ed6de1fa702ef70bd6ce
Password protect
https://www.digitalocean.com/community/tutorials/how-to-set-up-password-authentication-with-nginx-on-ubuntu-14-04
Other options
Let code-server
handle its own encryption
Another option is to not include the --no-auth
option and let code-server
do its thing. Here is a resource for more information on this would work on Digital Ocean
https://github.com/codercom/code-server/blob/master/doc/admin/install/digitalocean.md
Use coder.com
I should also mention that coder.com has a cloud service for this.
Overview
Running VS Code on the cloud untethers the developer from their workstation. One could install their plugins, configure the editor to their liking, and work directly from the could. The environment is always there, ready to go.
Top comments (6)
So for the SSH Tunneling/ Port Forwarding section is there a reason why you did the
0.0.0.0
? Because if you use that instead of just leaving that off (i.e.(or doing
localhost
) then that means, if you don't have a firewall on your machine that is actively blocking port 3000, anyone will be access that port that is one the same network as you. Since you are just referencing accessing localhost in the article I think it would make more since to just drop the0.0.0.0
so you don't expose unnecessary ports from your machine (or in this case from the remote machine).really cool post though, thank you 😁
have you tried running other docker container in parallel? I tried doing that a few weeks ago but on coder.com but support told me they are not there yet...
for my use case to make sense developing remotely I would really need to be able to run other docker containere
This is exactly what I wanted for a long time - been trying to hack some HTML5 screen sharing tools to achieve the same objective.
Naturally this would be 1000x better.
I contribute to about 20 different repositories. Curious, how would this setup handle that? Would I need a new instance of this per repository, or could vscode access multiple machines like it can locally? Also, is this limited to docker/Linux? I run windows and FreeBSD in my environment, curious to know how this would Translate, too.
in theory you should be able to access different repo's, but you should also be able to use something like this plugin: marketplace.visualstudio.com/items... to aid in repo switching if needed.
also, it looks like they package all the dependencies in a docker container so if you wanted to run it somewhere else, you would have to make sure all the deps are installed on the target machine. aside from that you should be able to run it in a vm (or vagrant box) with relative ease on windows/freebsd. looks like freebsd is trying to get it working: wiki.freebsd.org/Docker , and for windows you should be able to use docker desktop.
Really interesting concept.
I want to try it out but sadly, I'm not receiving the verification code by SMS :(