Creating a Docker Container

Since Devin has access to a Terminal and can configure and run software on its own server, setting up a Docker container is well within its capabilities.

Our sample application is a Go project with MongoDB as the data store. This session is Devin’s version of a Pull Request that a real developer made to an open source project. Follow along with the live run here.

Start With a GitHub Issue

We start with the original GitHub issue:

Next, we can write a simple prompt for Devin based on what this Issue is looking for. We instruct it to read the above GitHub issue for additional context, but also give it our own summary of the proposed solution and what we want Devin to produce.

Investigating the Codebase

Devin starts off with an investigation step where it reads our linked GitHub issue and scans the actual code and configuration files of the project for required dependencies.

After its analysis is complete, Devin moves on to install Docker on its local machine and then create our initial Dockerfile, docker-compose.yml, and .dockerignore so that it can begin testing the container setup. It also configures our .env file so that the application can run with the newly configured container backend.

Testing the Container

Devin then moves on to test each container, starting with our MongoDB server and then moving on to our Go environment. Once the containers are up and running, Devin moves on to testing the application itself. From reading through Devin’s Command History I can see that it found our Swagger API definition and loaded it into the built-in Browser to see how the backend API works.

Devin then put together a curl request to test that the backend API is running and returning results as per its design spec.

Debugging

Since we get a Connection refused error, Devin immediately moves on to debugging and correcting the Docker configuration. This is a common pattern where Devin can self-correct errors as it goes through a session. Devin quickly corrects the configuration issue, restarts the Docker container, and summarizes its completed work for us.

When we compare Devin’s work to the PR on the actual project, there are some notable differences and improvements:

  • Devin sets up a docker-compose.yml file in addition to our Dockerfile. This gives us some more specific orchestration settings like defining how our network works, how our volumes are configured, and which services depend on one another.
  • Devin changes the build process from go mod tidy to a method that allows us to cache some of the dependencies in our Docker build.
  • Devin builds a statically linked Go binary rather than a dynamically linked one, which should be lighter weight for our docker build.
  • Devin configures our CA certificates for HTTPS, and lets us use a .env file for configuration rather than passing in environment variables directly.
  • And most notably, Devin adds a MongoDB service in our Docker config which the PR on the project does not. It assumes the developer has a separate MongoDB instance running already.

In 13 minutes, Devin has successfully put together our Docker container for this project’s backend using best practices, tested it, and written a comprehensive summary of its work. Try your own containerization prompt on your own codebase today by signing up for a Devin account for your team.