2016-05-01

Visual Studio Code served from Docker

How long does it take to set up your development environment? How long does it take a new software engineer on your team to set up their dev environment? When you want to try out a new programming language, how much time do you spend figuring out what tools to use before you actually try out the language? I'd like to be able to git clone a project, type a single command, and be able to edit and debug it. I'd like the editor to be tailored to the language and domain of the project. Together, we can simplify the development experience using recent releases from Visual Studio Code and Docker with the age-old X Window forwarding.

Visual Studio Code released 1.0 in March and they have a marketplace with a lot of great extensions like Go, F#, and Rust.  Also in late March, Docker for Mac and Windows Beta began. I recently joined the beta program and love how much simpler they make it on both platforms. In this post, I'll cover Docker for Windows Beta, but the scripts should be easy enough to adapt to your Docker host environment. I'll cover installing it, a good free X Server for Windows, and a script to launch Visual Studio Code with the Go extension and its dependencies installed. More details about that golang-vscode Docker image will be in a subsequent post. I'll just say that it is capable of coding real Go projects with code completion and debugging. Here is a screenshot of me debugging my first Go language pull request to Nut using the same docker image, but with Docker for Mac.

X Windows Server on Windows

VcXsrv looks like a good choice for an X Server on Windows. It is free, maintained, has good ratings, automatable, and easy to install via Chocolatey: `choco install -y vcxsrv`. That installed the most recent 64-bit version 1.18.1.1 released in March on my machine.


You you can then start it by running XLaunch and selecting multiwindow with no access control, but we will automate that with this PowerShell:

$env:path="$env:ProgramFiles\VcXsrv;$env:path"
vcxsrv -multiwindow -ac

Docker for Windows Beta

You can sign up, then download (when accepted) the beta of Docker for Windows. The InstallDocker.msi for 1.11 beta 9 is only 93.3 MB. Pretty small and performant. It ditched VirtualBox in favor of the built-in Hyper-V. Windows 10 Pro is required with the update from November or later. I'm running build 10586.218 from April 12th. You can see update history details here and get your exact version by running (window+r) winver. If you are lagging on updates, you will get this message:


If you don't feel like upgrading, Docker Toolbox will work too, but with a bit more effort because you have to use Docker Machine to create a VM and then set the environment so Docker Engine knows about it. With Docker for Windows, one is created for you behind the scenes, but you can still pop open Hyper-V Manager to take a look. That Windows version added Hyper-V features that Docker probably needs. I'm guessing it might be nested virtualization.


With Docker installed, you will see the whale in your taskbar icon, which is right next to the VcXsrv icon in this screenshot. You can right click on either of them for action like showing about.


After the install, you now can run `docker` from PowerShell. It is that easy.

Starting Visual Studio Code from Docker

This is scriptable, but I want to walk you through how it works. We are going to start Visual Studio Code within the Docker container. VSCode wouldn't start up as root, so I created a vscode user on the image. We will switch to that user `su - vscode` and start VSCode in the current directory of /home/vscode `code -w .`. We will run the latest build of image ctaggart/golang-vscode that I built via Travis CI with this code under an MIT license. We will send the VSCode window to the X Window Server over a TCP/IP connection on default display 0 (tcp port 6000). To do that, we set the DISPLAY environment variable in the container to to the IP address provided by the Docker host. Run ipconfig and look for "vEthernet (DockerNAT)".


Using that IP address, we can set the env var and start VSCode. `docker run` will pull (download) the image if it doesn't exist locally. When these command finish, VSCode will pop open, assuming you have X Server running already.

$ip='10.0.75.1'
$cmd="export DISPLAY=${ip}:0; code -w ."
docker run --rm ctaggart/golang-vscode su - vscode -c $cmd

Start via PowerShell Script

Just download and run run-dockerforwindows.ps1 to do most of the above automatically. :-)

# start VcXsrv if it is not started yet
$prog="$env:ProgramFiles\VcXsrv\vcxsrv.exe"
if (! (ps | ? {$_.path -eq $prog})) {& $prog -multiwindow -ac}

# get the IP address used by Docker for Windows
$ip = Get-NetIPAddress `
    | where {$_.InterfaceAlias -eq 'vEthernet (DockerNAT)' -and $_.AddressFamily -eq 'IPv4'} `
    | select -ExpandProperty IPAddress

# start Visual Studo Code as the vscode user
$cmd="export DISPLAY=${ip}:0; code -w ."
docker run --rm `
    --security-opt seccomp=unconfined `
    ctaggart/golang-vscode `
    su - vscode -c $cmd

Conclusion

Running Visual Studio Code from a Docker image with a set of a bundled extensions is a great way reduce development environment setup time, provide consistent environments, and try out new languages. I hope that it catches on and is made even easier and performant (especially on Mac). I even started contributing to Nut to help automate and share some of the Docker setup. Ideally, I'd like to be able to git clone a project and run `nut code` to start Visual Studio Code with everything I need to begin coding and debugging.