Microsoft has published Visual Studio Code v1.35 and besides using a new icon it comes with support for the previously insider-only version of the Remote Development Extension. This allows developers to open their projects in a different environment, either local or remote.
The most propagated use cases are connecting to your Linux subsystem (WSL), a container running on a local Docker instance or a remote server using SSH. Hidden in the ‘Advanced Containers’ section the documentation also describes how to combine the latter two: Open a project on a remote server within its own Docker container. I have tried it and would like to share the setup process and obstacles I faced.
1. Game Plan and Prerequisites
1.1 Game Plan
The idea is to use any device that is capable of running VSCode to connect to a remote server that is storing all our development projects and also runs Docker containers suited for each type of project.
Using this setup will take care of three issue you might face when working on multiple devices (Home / Work / Laptop):
- “My device is not strong enough for development and building”
By using VSCode Remote Development, you can store all your development projects on a single machine (most likely a rented server) that has enough power to handle all your development needs and probably even more (multi user setup).
- “My device does not have all the dependencies needed installed / My dependencies differ among the devices used”
Good News: By using VSCode Remote Development you will no longer have to install project dependencies locally. All node_modules you had to install and synchronize are now stored in the containers on our remote machine into which we mount our project files.
You want to check if your React Application is still working with the new TypeScript version? Just use a different container with the latest TypeScript installed and try it!
- “My devices all have different VSCode extensions installed”
Using the Remote Development Extension, all your favorite extensions can be stored on the development server. When working on a remote project, you have the option to install an extension either local or remote. This means, you have all your Python extensions at hand when connecting to a Python container and all your React extensions up and ready when connecting to a React container.
(If you prefer to keep extensions locally, just set the option during the installation.)
1.2.1 Server (Remote)
In this scenario, I am using a Linux based server running Debian 9, containing a Quad-Core Intel Processor, 12GB RAM and 2x 750GB SSD Storage in RAID I.
For testing, you probably want to go with less resources, or even just spin up a virtual machine to try the concept first. Following the official documentation, Alpine Linux instances are not yet supported, so keep that in mind when choosing a distribution.
To make the server VSCode Remote Development ready, only two applications need to be installed:
- Docker – https://docs.docker.com/install/linux/docker-ce/debian/
(To create containers with your ssh login, remember to add the docker group, as described in https://docs.docker.com/install/linux/linux-postinstall/ !)
The server is now ready to be used for remote development!
1.2.1 Client (Local)
Although I have not tested the client setup with all three major operating systems, it should be the same process. If something is fundamentally different, I will update this post. These steps follow the official documentation published at https://code.visualstudio.com/docs/remote/containers-advanced.
By default, if you want to open a project in a docker container using VSCode, it will connect to your local Docker socket, create a container, if needed, and mount your project files. In our scenario we want to connect to the docker instance running on our remote server. However, in my early tests, I was not able to establish a connection to the remote machine, when Docker was not installed locally. VSCode complained about Docker not being installed. I think, it is checking for Docker being present before even trying to connect to it. This means, eventhough we will not use the local Docker instance (for this setup) we have to install it on the client.
I consider this to be not the expected behavior. Keep a close eye on future releases of Remote Development, the need for a local Docker installation might vanish in the future.
Make sure you have the following applications installed locally:
- Visual Studio Code 1.35 or higher
- Extension: peterjausovec.vscode-docker
- Extension: ms-vscode-remote.vscode-remote-extensionpack
- OpenSSH compatible client (+ key agent if needed)
The client is now ready to be used for remote development!
1.3a Clone existing project on remote
If you do have an existing project, you have to move / clone it to the remote server before starting development. In my testing environment, I created a folder /development which holds all the projects I want to work with. In this case I would run git clone xxx within /development. Keep the absolute path at hand, as we will need it later.
1.3b Prepare remote for new project
If you want to start with a fresh project you need to create an empty folder first. This will be the mount point for our development container. In my testing environment, I created a folder /development which holds all the projects I want to work with. In this case I would run mkdir xxx within /development. Keep the absolute path at hand, as we will need it later.
2. Establishing a new connection
2.1 Connect client to remote docker instance
To connect to the docker socket on the remote machine without exposing it publicly, we are establishing a SSH tunnel. This has to be done every time you want to connect to the remote Docker instance. In addition, we have to tell VSCode where it can find the Docker socket it should use for its Remote Development sessions.
Make sure you run the following two commands every time before opening VSCode (or automate it on startup smh):
ssh -NL localhost:23750:/var/run/docker.sock user@hostname
Replace user with your SSH login and hostname with the remote server ip / fqdn. The command to set the ENV VAR might be different depending on your OS. Keep this terminal open until you are done developing on the remote server.
2.2 Connection file creation
You might want a local folder where all connection configuration files are stored. In my testing environment this folder is placed at D:\dev\remote. If you want to add a new connection, start off with creating a new folder named after the project (empty). Now open that folder in VSCode and follow these steps:
- Hit Ctrl+Shift+P to open the command line
- Select Remote-Containers: Create Container Configuration File…
- Select a template from the list (these are default templates, that you can modify later), this will create a new folder .devcontainer containing devcontainer.json and a Dockerfile
- In devcontainer.json add the following two lines to add the mount point for your container (replace the source path with the absolute path from above)
12"workspaceFolder": "/workspace","workspaceMount": "src=/development/xxx,dst=/workspace,type=bind"
- Adjust the Dockerfile to your delight
2.3 Establish connection
Save your changes. In the bottom right corner of VSCode you should see a popup saying that a dev container configuration file has been detected. Click Reopen in Container. A new container is now being created on your remote system. Your terminal will keep you updated on the progress. Once done, you can open a second terminal which will automatically spawn within the newly created container.
If you cloned / created a project before, you can start developing right away. If you want to create a new project you can run all the known commands (git clone, create-react-app, …) within the container. The files will be created at the mount position specified earlier.
If you want to connect to the container / project next time, just open the local folder containing the devcontainer.json. The same popup will appear and you can simple establish the connection again.
As the Remote Development Extension is still in preview state and subject to change, this post might be updated in the future.