Using docker containers for development

Created on March 16, 2023 at 7:40 pm

Docker is a technology that allows users to bundle an application and run it within a loosely isolated environment referred to as a container. These containers are lightweight and self-contained, containing everything required to run the application without reliance on the host’s existing software. Containers can be shared effortlessly, ensuring that all recipients have access to the same working container.

Docker has become well-known for its deployment of production services such as application services and databases on enterprise servers or cloud instances. However, developers are increasingly employing containers for scenarios beyond deployment, including continuous integration, test automation, and complete software development environments, also known as development containers. These containers define a consistent environment in which an application can be developed before it is deployed.

One may question the benefits of containerizing the development environment. Have you ever found yourself cluttered with projects, libraries, languages, configurations, and tools when working on a new laptop or server? Wouldn’t it be beneficial to “restart” your software development environment to its original state?

Development containers provide a repeatable setup and consistent stateless development environment, allowing users to leave the underlying host free of project dependencies, specific language versions, and other factors. Furthermore, development containers enable users to utilize only the host machine’s computing resources. Finally, since the development environment is containerized, it can be replicated across many different systems with the Docker engine installed, ensuring a consistent development environment.

Numerous tools and services support the use of development containers, but Dockerfiles provide an option to customize your environment directly. Dockerfiles can extend images, add additional native OS packages, or make minor edits to the OS image. While many development images have been created by Microsoft available in Docker Hub, it is possible to create one from scratch.

To build a base development image, a parent image is required. The image contains several runtime versions for popular languages, including Python, Node, PHP, Java, Go, C++, Ruby, and .NET Core/C#, as well as many popular tools and package managers. Using a custom Dockerfile, you can extend this image and add whatever you need.

For example, the Dockerfile shown above extends the parent image by first installing neovim and tmux to aid the development workflow. The user is then changed to codespace, and the working directory is set to the user’s home directory. Finally, configuration files for each tool are copied from the local machine.

Assuming the Dockerfile is in the same directory, the development image can be built with the following command:

$ docker build -t devcontainer .

The following command can be executed to start a development container from the newly created image:

$ docker run –privileged -it devcontainer bash

The -it flag opens an interactive container instance using bash as the Unix shell, and the –privileged flag starts the Docker container in privileged mode, granting the container root capabilities to all devices on the host system. This is beneficial when Docker is part of the development workflow. In addition, a volume can be mounted using the -v flag to persist data across different development containers, and a port can be mapped using the -p flag if developing a web application.

Connecting to Connected... Page load complete