Onboarding New Team Members Simplified with Dev Containers
Tags: vscode, docker, webdev, showdev
Published: 2023-08-17 20:46:23

# Onboarding New Team Members Simplified with Dev Containers

Ever grappled with the challenges of onboarding new team members? Initializing a development environment can often be a long-winded affair, especially when one needs to adjust to configurations from prior projects. What if I told you there's a strategy to alleviate such pain points and ensure a uniform development environment across diverse operating systems, including Linux, Windows, and Mac?

In recent times, several IDEs have incorporated support for Dev Containers, and in this piece, I'll elaborate on this concept using Visual Studio Code.

## Understanding Dev Containers

For those seeking a deep dive, Visual Studio Code's official documentation provides a comprehensive guide on Dev Containers and the various configuration possibilities. Check out the documentation [here](https://code.visualstudio.com/docs/devcontainers/containers).

In a nutshell, here's how Dev Containers work:

1. Define your environment via a `Dockerfile` (optional) and `devcontainer.json`.
2. Build and start the container via VS Code.
3. Integrate the repository within the live container (automatic).
4. A server instance is launched in the container by VS Code (automatic).
5. The local VS Code instance connects to this server instance (automatic).

## Why Use Dev Containers?

As you may already have noticed, defining environments using Dockerfile's has become a de facto standard for production services.
We can now do the same for our development environments, defining them in code to gain:

1. **Consistency Assured**: With Dev Containers, uniformity across the team's development environment is a given, dispelling discrepancies in configuration.
2. **Effortless Rollbacks**: Bumps on the road? Simply rebuild the current or revert to a former container state and resume your development.
3. **Streamlined Maintenance**: The upkeep and update of the development environment are rendered straightforward and less prone to errors with Dev Containers.

## Tangible Benefits Gained

By adopting Dev Containers in my current project, we managed to reduce the onboarding for a new developer to:

- Permission for the git repository access.
- Having Git and Docker installed on their local machine.

We've managed to trim down the setup to approximately 2 minutes of hands-on work. 
This is succeeded by about 10 minutes of building time for the Docker Image, with an added 3 minutes for the installation of code dependencies within the container.

So, for your project, we can guarantee a working setup within 15 minutes.

> This can be sped up further by pre-building the image and storing it in a repository.

## The Flip Side: Potential Limitations

While Dev Containers offer numerous benefits, it's essential to acknowledge the potential downsides:

1. **Overhead**: Owing to the containerization layer, Dev Containers introduce some overhead.
2. **Restricted File Access**: On Windows, gaining access to files within the container is not straightforward (depending on your setup).
3. **Intermittent Rebuilding**: On rare occasions, a container rebuild becomes necessary for seamless functioning.

> We could not isolate the root cause yet, but as this occurs so rarely, we did not invest more resources in solving it.

---

## Setting Up Dev Containers

To get started with a simplified Dev Container setup for my current project, you can use this template [NicoVogel/dev-container](https://github.com/NicoVogel/dev-container).

### Template Setup At A Glance

To grant you a brief overview of what the template includes:

- Use of `pnpm` for improved performance.
- `playwright` for end-to-end testing.
- Enabled "docker in docker" via socket mount, allowing Docker to be used within the development environment.

To leverage the full potential of `pnpm`, you need to combine it with Linux's filesystem instead of Windows' `ntfs`.
Dependencies are mostly small files, and Linux is just far superior for this workload.
Therefore, we have opted to clone our code into the Linux's filesystem and mount it into the Dev Container. 

> This also speeds up `git`.

For Windows users, two potential routes are:

1. **WSL2**: Establish a personalized Linux and incorporate the repository therein.
  - `+` Easy to access files later on
  - `-` Setup guide for Linux required
2. **Clone Repository into Container Volume**: Use a feature from the Dev Containers extension to clone it directly into a docker volume.
  - `+` No setup needed whatsoever
  - `-` You can access the files in the file explorer, but you need to find them first via docker commands.

Depending on the skill sets of your developers, one or the other may make more sense for you.

#### Features Omitted from the Template

The main feature omitted is the artifactory integration.
You can also extend your container setup to:

- Store the Dev Container image in Artifactory
  - This includes proxy settings and custom company certificates.
- Mirror npm packages in Artifactory.
- Provide a login script for Artifactory after startup.

> The `scripts/setup.py` is the login script for Artifactory, in case anyone needs it.

## Tailoring The Template

To customize the template for your specific needs, follow these steps:

1. Duplicate the template folder, renaming it `.devcontainer`, ensuring its location is at your project's root.
2. For those with a proxy, modify the parameters in `.devcontainer/devcontainer.env`. If not, simply clear the file contents.
3. Set a base image that contains your company's certificates (if you have any) and adjust the `FROM` directive in `.devcontainer/Dockerfile`. Alternatively, you can use any Ubuntu base image.
4. Update the list of extensions that should be preinstalled automatically in `devcontainer/devcontainer.json`.

With these adjustments in place, you're ready to use the VS Code command `Dev Containers: Reopen in Container`.

---

## In Retrospect

Dev Containers, as described using Visual Studio Code, offer a solution to simplify onboarding and ensure a consistent development environment across different operating systems.
By defining the Dev Environment as Code, Dev Containers guarantee consistency, easy rollback, and simplified maintenance.
This leads to a reproducible setup time and significantly reduced onboarding efforts.