Introduction to Dev Containers

September 19, 2024#Tools
Article
Author image.

Sarah Dutkiewicz, Senior Trainer

Picture this - you’re a consultant who happens to be working on projects in different versions of Node.js. Or maybe you’re a consultant who happens to be working with different versions of Python or Ruby. Or maybe you’re a consultant who works with projects in various languages and wish you didn’t have to have all of the development tools locally. Maybe you have to deal with these technologies on Windows, which is yet another pain point.

I maintain a couple Gatsby projects and recently was brought into a Ruby project for a community project. Working with package.json and Gemfile setups remind me of why I don’t like having all these tools installed locally. This gets painful to maintain multiple versions and switch around for projects. If the projects have dependency issues, that gets even more chaotic to manage.

However, last year, I caught a talk on development containers - dev containers for short. I’m here to tell you about how awesome they are and why I recommend others use development containers for their projects.

What are Dev Containers?

Dev containers are lightweight, portable environments designed to standardize the development experience across different machines and operating systems. They allow developers to package their entire development environment - tools, dependencies, and configuration - into a containerized format. This ensures that the code you’re working on will behave the same no matter where it’s run, whether it’s on your local machine, someone else’s, or even in the cloud.

In my most recent situation, as I joined the Ruby project, I realized that I haven’t had Ruby installed on my machines in over a decade. Now that I am getting back into it, I still don’t want to install it on my machine. So… I created a dev container with Ruby and the project’s prerequisites! Since I run Windows locally and know the pains of developing Ruby on Windows, I opted for a Linux-based container. This is working really well now! 🎉

Dev containers typically use Docker to virtualize the environment, providing a clean, isolated workspace without conflicting with your host machine’s configuration. The development environment can be defined using a devcontainer.json file, which details all the tools, extensions, and services your project requires, and Visual Studio Code supports this setup natively.

In essence, dev containers solve the “works on my machine” problem by ensuring that your entire development setup is repeatable and sharable.

What are the Prerequisites?

In order to run dev containers, you need:

  • Container Runtime - Docker is the most commonly used runtime. Others aren’t well-documented, if at all. Some posts suggest other Docker-compliant CLIs may work.
  • Developer Environment
  • Dev Container Configuration - devcontainer.json
  • Operating System support

What IDEs and Editors work well with Development Containers?

These are some of the IDEs and editors that support dev containers:

My Ruby Dev Container Solution

For the Ruby project, I needed to make sure I had Ruby, Active Record, and SQLite3. I started by creating a container but realized I needed to do a bit more in building my container. If you find that what you need cannot be configured in devcontainer.json alone, you can reference a Dockerfile as part of building the dev container. In the case of my Ruby project, I need to install SQLite3 as part of dev container creation.

This is my Dockerfile:

# Use Ruby image
FROM mcr.microsoft.com/devcontainers/ruby:3.1-bullseye

# Install SQLite3
RUN apt-get update && apt-get install -y sqlite3 libsqlite3-dev

# Clean up apt cache to reduce the image size
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

This is my devcontainer.json:

{
  "name": "Ruby DevContainer",
  "build": {
    "dockerfile": "Dockerfile"
  },
  "features": {
    "ghcr.io/devcontainers/features/common-utils:1": {},
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/ruby:1": {
      "version": "3.1"
    }
  },
  "postCreateCommand": "gem install bundler rake activerecord sqlite3",
  "customizations": {
    "vscode": {
      "settings": {},
      "extensions": [
        "rebornix.Ruby",
        "castwide.solargraph"
      ]
    }
  }
}

Notice that as part of build in devcontainer.json, I reference the Dockerfile. You can also use Docker Compose.

Now, I can run the Ruby scripts I need for my community adventures without having to have the Ruby tools installed on my machine! Dev containers save the day!

What about the Gatsby Sites?

Those sites are also headaches to maintain on Windows. Have you ever run into a Node.js site that uses node-gyp and see the pains it brings in a Windows environment? 😖

Those headaches went away when I containerized each of the Gatsby blogs I work on. I will talk about using dev containers with Gatsby in another post. Stay tuned!

Conclusion

Dev containers are a game-changer for modern development. They eliminate the friction of environment inconsistencies, allowing you to develop with confidence, no matter what platform you’re on. Whether you’re managing multiple projects like I am, or just want to avoid the hassle of configuring dependencies on different machines, dev containers make your development workflow seamless and reproducible. By isolating the development environment in a container, you can say goodbye to “it works on my machine” headaches and focus on writing code. If you’re struggling with setup issues or want a more efficient development experience, give dev containers a try. They could save you a ton of time and frustration!

References

If you want to learn more about dev containers, check out the following references:


Copyright © 2024 NimblePros - All Rights Reserved