Visual Studio Code + Github Codespaces + Kubernetes = Bonkers

Jeremy Gordon
5 min readAug 16, 2021

The dream: sit down at any computer, select a branch (or PR) on Github, and get a complete copy of your cloud app and its infrastructure available to iterate on using your personalized development environment in literal seconds.

Well, if your cloud app is built on Kubernetes, and you’re a Visual Studio Code fan, that dream is a reality today. For the impatient, you can jump to the end of this post for how to try this out immediately.

A key part of realizing this setup is the Visual Studio Code Remote — Containers extension. This extension lets you use a remote Docker container as a full-featured development environment. Not only do the files you are editing get checked out into the remote container, but a substantial part of Visual Studio Code (and many of its third party extensions) actually execute inside the container.

If you’ve ever tried to edit a large code base hosted on a network mounted drive, you know features like find in files or those that depend on indexing source code are deal killers. Modern development environments like Visual Studio Code rely on querying language servers for everything from highlighting coding errors to symbol completion; language servers that are constantly iteratively scanning, lexing, parsing and compiling up to millions of lines of code.

Visual Studio Code’s ability to run big parts of itself inside of a remote Docker container makes it not only practical for modern development features to be similarly performant to developing locally, but in many cases to be more performant than developing locally when working on beefy cloud infra.

Did someone say beefy cloud infra? Enter Github Codespaces.

Github Codespaces makes it downright trivial to allocate and manage on demand cloud infra from two to thirty-two cores (well, third-two cores in the near future). On demand cloud infra is nothing new, but it’s typically something we think about with respect to compute workload for backend applications. Github Codespaces makes it practical and easy to allocate and manage on demand cloud infra for use as your own personal development environment.

So how does this work?

You add a configuration file called “devcontainer.json” to the root of your Github repository that configures the setup of a Docker container to be launched at your whim. When launching the Docker container, Visual Studio Code will check out a copy of your source code repository into the container, along with cloud synchronized copies of configuration settings like your fav color theme, keyboard bindings, etc.

You can instruct Visual Studio Code to launch this Docker container on your local laptop, on the linux box under your desk, or any cloud hosted Docker daemon that you can SSH to. Super. Cool. As an aside, how to connect to the linux box under your desk from the corner coffee shop? Check out Tailscale, the hands down easiest and coolest VPN I’ve ever used.

Things start to get interesting when you navigate your browser to Github Codespaces and instruct it to create and connect to an on demand Github hosted Docker container based on a Github repository. The Github Codespaces webpage can launch and connect a native copy of Visual Studio Code on your laptop, or instead navigate to a complete browser based copy of Visual Studio Code. That’s right, no native app install necessary, complete with all your settings and extensions.

I know, I know, sounds like a gimmick? I mean, how good could a browser based copy of Visual Studio Code be? Turns out, really good. But it’s not just a neat parlor trick; it enables new kinds of workflows around branches and pull requests, and generally fits in nicely in the new normal of our pandemic era remote first world.

Ok, but where things start to get really interesting is running a sandboxed copy of Docker inside the development Docker container launched by Visual Studio Code (so called docker-in-docker). Still with me? Let’s go another inception level deeper and run an entire Kubernetes cluster in that sandboxed copy of Docker using kind (“Kubernetes-in-Docker”). Originally developed to help integration test the development of Kubernetes itself, kind is awesome at spinning up and running lightweight, but fully featured Kubernetes clusters.

From here, we can use Helm to install and manage a complete local copy of your app’s infra into your kind Kubernetes cluster; from local copies of cloud staples like MySQL and RabbitMQ to sandboxed instances of S3 and GCP via Cloudserver.

What about your cloud app itself? You can bind mount your editable source code files from the development Docker container launched by Visual Studio Code through kind and into a version of your Kubernetes pod that watches, rebuilds and restarts your app on changes.

What about running and debugging tests? Same, same. Bind mount your source code files into a test Docker container that watches and runs tests. Port forward debug ports back into the development Docker container launched by Visual Studio Code to be able to set breakpoints, single step and the like.

Ok, but how do you interact with your app the way a user would? Visual Studio Code and Github Codespaces have you covered there too. Visual Studio Code allows you to configure port forwards back to your laptop; in many cases auto-detecting and creating them for you. With Github Codespaces, you get private or public URLs to allow another browser tab on your laptop (or a teammates) to interact with your app under development.

You don’t need Github Codespaces to accomplish all this. You can achieve much of this with Visual Studio Code on your laptop connected to Docker on your laptop or to your linux box under your desk. But the fact that Github Codespaces only charges you for when you are actually using the remote container (effectively hibernating it if you walk away for more than 30 minutes) means developing on your beat up old Chromebook completely in a browser can be faster than on that top of the line 16" Macbook Pro.

Bonkers.

Less talk, more action?

Navigate to https://github.com/codespaces and click “New codespaces”. When prompted, enter jeremysf/vscode-kind as the repository to start your new Codespace from.

Once your codespace is running, in the built-in terminal in Visual Studio Code, run the script “create_k8s_cluster.sh”. Boom. You now have a running Kubernetes cluster.

Running, but um, empty. Let’s populate it with some services. Run the script “helm_upgrade.sh”. A quick “kubectl get services” will show a bevy of running services.

Enjoy!

--

--

Jeremy Gordon

Now: something new! Then: CTO @projector, VP Eng @twitter, game industry refugee (SNES — PS3). Also: coaching HS hoops and soccer. @PositiveCoachUS disciple.