GitHub, Professional

GitHub Codespaces and Local Containerized Development

Introduction

Recently GitHub has announced the introduction of GitHub Codespaces. This offering empowers developers to get started quickly on a virtualized desktop experience frontended by a user’s browser running VSCode. This environment is launched behind the scenes as a Docker image which is published to the Codespace.

This technology has empowered the developers at GitHub to get started in a matter of seconds vs hours required to download all the necessary packages. Don’t believe me? Check out in their own words.

Something I want to outline here is that Codespaces is a paid service. If you don’t have access to it you can still create a local containerized development environment to speed developer onboard time and drive developer environment consistency.

For transparency I leveraged Codespaces in my recent conference session on the Many Flavors of IaC for Azure at Heartland Developer Conference 2022. Can check out the conference content here. Additionally I have created an introduction post on the project.

This post won’t cover how to user Infrastructure as Code. If interested check out the Many Flavors of IaC for Azure repository or my posts on Bicep and Terraform.

One last disclaimer, I am novice on container development so any feedback would be appreciate!

Background

For this conference I decided to leverage codespaces. From hear on out for simplicity I will refer to the process as “codespaces”. Know though this same process can be leveraged via local containerization which I will also outline.

The background here is I have created a repository to help illustrate the IaC choices one may have in Azure. At the time of this writing ARM, Bicep, Terraform, and Pulumi are currently supported. If you are unaware of these tools there are just some of the languages one can chose when developing IaC in Azure.

All of these tools require their own software for deployment, development, and management. To help ease the learning curve around these I decided creating a “codespace” would be ideal. This process would essentially create a container preloaded with all the necessary VS Code extensions and CLI tools installed. Again I am an advocate in DevOps where I believe empowering teams to deliver a higher quality product faster is essentially. Thus I have applied that in terms of delivering learning material.

Configuration

Configuration a GitHub repository for codespaces was a lot easier then I anticipated. I essentially followed the VS Code documentation. The long and the short of this is a new folder in the repository named .devcontainer . Within this folder would be the appropriate DockerFile and devcontainer.json file.

Codespaces will automatically detect the files and enable the codespaces option if it you have access to run code within a codespace.

devcontainer.json

The devcontainer.json will contain the basic arguments for a virtualized environment. This would contain items like OS versions, VS Code extensions, and common features you can enable. For my purposes I have a fairly simple one:

// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/ubuntu
{
	"name": "Ubuntu",
	"build": {
		"dockerfile": "Dockerfile",
		// Update 'VARIANT' to pick an Ubuntu version: jammy / ubuntu-22.04, focal / ubuntu-20.04, bionic /ubuntu-18.04
		// Use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon.
		"args": { "VARIANT": "ubuntu-22.04" }
	},

	// Use 'forwardPorts' to make a list of ports inside the container available locally.
	// "forwardPorts": [],

	// Use 'postCreateCommand' to run commands after the container is created.
	// "postCreateCommand": "uname -a",

	// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
	//"remoteUser": "vscode",
	"features": {
		"terraform": "latest",
		"git": "latest",
		"azure-cli": "latest",
		"powershell": "latest",
		"dotnet": "latest"
	},
	"extensions": [
		"ms-azuretools.vscode-bicep",
		"ms-azuretools.vscode-docker",
		"ms-dotnettools.csharp",
		"pulumi.pulumi-lsp-client"
	]
}

I leveraged the Dev Container VS Code Extension to help create the initial devcontainer.json. Was a simple prompt where I could select common features via an easy checkbox.

To install extensions I realized need to leverage the Identifier property on the VS Code Marketplace. This will tell the container to download the explicit extensions identified.

DockerFile

The DockerFile I recognize is where the real “art” of containerization takes place. This is something I am still a novice in; however, for this particular use case I needed to install and configure the Pulumi CLI. I mean who wants to download an additional CLI that they are just looking to experiment with? For this I just told the DockerFile to download the Pulumi Docker package:

# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/ubuntu/.devcontainer/base.Dockerfile

# [Choice] Ubuntu version (use ubuntu-22.04 or ubuntu-18.04 on local arm64/Apple Silicon): ubuntu-22.04, ubuntu-20.04, ubuntu-18.04
ARG VARIANT="jammy"
FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}

# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
#     && apt-get -y install --no-install-recommends <your-package-list-here>

FROM pulumi/pulumi

View in Codespaces

Update: GitHub has since announced 60 hours of free Codespaces per month for all users.

To view this repository in a Codespace one just needs to click the code button and select the desired codespace:

Screenshot of the Codespace in GitHub
Screenshot of the Codespace in GitHub

When clicking the Codespace you will see a screen similar to below:

Screenshot of Codespace starting
Screenshot of Codespace starting

This may take a few minutes; however, once the Codespace is started and connected will see a VS Code editor like the one below:

Screen shot of VSCode in a Codespace highlighting the extensions and terminal indicate are remote session contained in Codespaces
Screen shot of VSCode in a Codespace

Take note that the VS Code extensions are loaded and installed in Codespaces. In addition the terminal shows the location is bein executed on a remote Codespace location.

This means the repository is COMPLETELY AGNOSTIC of ANY machine!!!

What if I don’t have Codespaces?

This is a fair question, fear not as you still can be part of the fun! Codespaces are essentially a container hosted by GitHub and running in a browser. This technology can still be used to create and run a container locally. This container will still install the VS Code extensions and execute in a containerized environment.

PreReqs

For this to work locally will require the following:

Configuration

This will be the same basic configuration as Codespaces. A .devcontainer folder with a devcontainer.json and Dockerfile stored inside of it.

In fact if you don’t already have the Dev Container extension installed VS Code is smart enough to detect this configuration in the source repo and prompt you to install the extension.

Running Container

There is a UI short cut of just selecting the Green arrows in the lower left:

Image showing UI Shortcut for Dev Containers
Image showing UI Shortcut for Dev Containers

This will bring up the Command Pallete:

Command Pallet with List of Commands associated with Dev Containers
List of Commands associated with Dev Containers

Alternatively can just open the command Pallet with Ctrl + Shift + P. You will want to select “Open Folder in Container…”. If Docker is not running there will be an error message stating such.

There will be a prompt for which folder to open as the container. If using the Azure IaC Flavors this would be the folder repo.

If successful will have an instance of VS Code that has extensions loaded into a container and the Terminal will indicate the “remote” execution:

VS Code running a folder as a container locally
VS Code running a folder as a container locally

Conclusion

This post covered GitHub Codespaces and Local Containerized Development. This environment cold be hosted via Codespaces or locally and both offer similar experiences. It can immediately create a development environment for an application or in this case for learning. All of this without any commitment or configuration on the end user. The experience thus far has been painless and straightforward. It is something I recommend anyone to take a look at.