The moment when I realized that I definitely need a remote dev environment was last year, at the beginning of the Covid-19 crisis. The first problem was the fact that I was working from several locations on a few different machines due to ever-changing lockdowns. The second problem was the degradation of internet connection and DNS, due to the sudden high demand for internet bandwidth. These dynamic circumstances finally pushed me to find a solution that is decentralized, stable, and accessible. I was actually surprised with the number of possible solutions for this problem, and in this article, I’m going to share the process that I used (and I’m still using) to set up VSCode and JetBrains IDEs on a remote machine.
When it comes to remote code execution, Visual Studio Code officially provides three ways to achieve this:
- Remote via SSH – Connect to remote and virtual machines with Visual Studio Code via SSH
- Work in WSL – Run Visual Studio Code in Windows Subsystem for Linux.
- Develop in Containers – Run Visual Studio Code in a Docker Container.
While all these implementations can be very handy, they were not suitable for my use case since I wanted my VS Code environment completely independent from my workstation. This means that I wanted to be able to access it from the browser, from any computer without the need to install any additional dependencies like VS Code, SSH client, or similar.
There is another interesting solution today called GitHub Codespaces. Honestly, I don’t know much about this and I’m not sure if it existed at the time when I investigated this concept last year, but GitHub describes it as:
Blazing fast cloud developer environments
Visual Studio Code backed by high performance VMs that start in seconds.
In a nutshell, it’s GitHub’s SaaS that provides VS Code on demand for a per-hour-based pricing model. This sounds better, but I would rather like my machine fully managed by me. Additionally I’m often in a position to have very cheap instances so this wouldn’t make sense in a financial way as well.
Since I didn’t find an appropriate official solution, I did a bit of investigation and found a tool called code-server (https://github.com/cdr/code-server).
Run VS Code on any machine anywhere and access it in the browser.
It sounds like exactly what I need, I decided to give it a try. There are several ways to setup code-server:
- installation shell script
- standalone releases
- linux packages
- brew package
Due to simplicity, I am preferring to use the shell script installation method together with the Caddy server. Before I proceed with the setup process, it is worth mentioning that the hardware requirements are a minimum of 1 GB of RAM/2 CPU cores machine, but this may vary significantly depending on your requirements and performance appetites. I have never used anything smaller than 8GB of RAM/2 CPU cores, but you’ll have to find the perfect proportion by yourself.
Installation script can be downloaded and executed with the following command:
# download and run the install script curl -fsSL https://code-server.dev/install.sh | sh # run code-server on boot sudo systemctl enable --now code-server@$USER
Afterward, the code-server needs to be exposed to the internet, and the official documentation describes four different ways to achieve this:
- Port forwarding via SSH
- Let’s Encrypt with Caddy
- Let’s Encrypt with NGINX
- Using a self-signed certificate
When this is finally done, the code-server URL can be opened, and if everything was set up properly, the user will see the Welcome to code-server message with the password prompt:
As stated on the welcome screen, the password can be seen/changed in config.yaml file. For password change to take effect, the code-server service needs to be restarted:
sudo systemctl restart code-server@$USER
That’s it, code-server is up and running:
JetBrains IDEs can be run remotely via their native tool called Projector. At the time I was searching for this kind of solution last year, this product didn’t exist, since it was launched 5 months ago (the first stable release was made in March 2021). For that reason, it still has certain imperfections, but I believe JetBrains will polish it and make an awesome tool out of it. Unlike code-server, this solution has two client implementations: web client (access your IDE through a browser) and native app (Linux, Mac, or Windows native app). Pros of the native app over web client are OS taskbar integration and availability of native keyboard shortcuts. Server side of the Projectors can be installed in three ways:
- Python installation script
- Docker images
- IDE plugin
I decided to use a Docker image as an installation method. This is the simple two-step process, pull and run the appropriate Docker image (I’m using WebStorm as an example, you can use any JetBrains IDE):
docker pull registry.jetbrains.team/p/prj/containers/projector-webstorm docker run --rm -p 8887:8887 -it registry.jetbrains.team/p/prj/containers/projector-webstorm
JetBrains does not explicitly guide you on how to expose the server to the internet. Once again I’m using the Caddy server, but feel free to use whatever fits your needs.
As soon as this is done, you can navigate to your server URL, and if everything went well, you should see a JetBrains user agreement that you need to read and confirm. Once this is done, your IDE should be up and running:
If we need to have several JetBrains IDEs on the same machine, we can just use a different host port for every instance. Since all files from the container will be lost if the container restarts, we need to mount a volume in order to persist data. This can be done using Dockerfile or run-container-mounted.sh script provided by JetBrains with container name as a parameter or you can simply mount folder while creating the container. It is important to say that the mounted folder (~/projector-docker by default) needs to be created manually to avoid permission issues.
The next step of the setup is securing your cloud IDE with the password. This can be done by setting your password through ORG_JETBRAINS_PROJECTOR_SERVER_HANDSHAKE_TOKEN and ORG_JETBRAINS_PROJECTOR_SERVER_RO_HANDSHAKE_TOKEN environment variables. The first one provides full access, where the user can fully control the IDE, and the second one gives read-only access where the user can only watch the UI, without the possibility to interact with it.
Whether you like the concept of cloud-based IDEs or not, they are here to stay. They will certainly not take over local IDEs, but they are great for certain use cases:
- workstation resources are low, or project is too large or demanding
- internet connection issues
- long-running tasks which require your machine not to be turned off for a long period of time
- workstation battery life constraints
- latency-sensitive development/testing
- location-based data security constraints
- need for tools that are not available on your host OS
The Coder team did a really great job with code-server, it’s an easy and well-documented solution that works without much hassle. On the other side, JetBrains Projector is still pretty difficult to set up and the documentation is fragmented so expect a couple of complications while you’re trying to assemble all of its elements. Anyhow, let’s take into consideration that it’s still a pretty fresh solution, and hope that in near future JetBrains team will put some effort to make it more stable and easier to set up.