So, last year I shared how we could integrate Codespaces into our AWS Lambda docker compose patterns. Since then Microsoft's Development Containers specification has come a LONG way. Everything is wrapped up nice and neatly at the containers.dev site. Take a look if you have not already seen it.
So why are Development Containers & Codespaces such a big deal? I can illustrate some Lambda & Kubernetes use cases below, but first I would like to spell out a few features that may be new to some. Including existing Codespaces users.
- The Dev Container specification at the lowest level of Codespaces is open to everyone and lots of tooling exists around it by a growing community.
- The specification has a reference implementation via a node Command Line Interface. Think of this
devcontainerCLI as a higher order docker compose. You can use this to run Codespaces projects locally!
- Atop of the CLI, there is CI tooling for GitHub Actions. This means you can use the same development container as your CI/CD environment.
So where are containers used in your organization or projects? Here are some phases that most of us can identify with. Where projects move from the left to the right.
Development: Most of us have tried to use docker or compose at some point. For example, the most common use of this area would be running a database like MySQL. Docker makes this easy.
CI/CD: Typically where we run tests and hopefully build and/or deploy our code to production. If you have used CircleCI before, again a database container here might feel familiar.
Runtime: Which is often our final container environment. We can think of this as production for most of us but it could be any container orchestration like Kubernetes, Lambda, or Fargate.
Today our Lambda SAM cookiecutters leverage SAM's build image via docker compose to ensure local development is within the same environment for our CI/CD tooling. We ended up with something like this image
At the bottom we can see the host platform typically associated with each of these stages. Because we use Docker, we can be cross-platform and consistent. The problem? ⚠️ Making up your own docker/compose patterns are a huge drag. From SSH patterns to Docker-in-Docker gotchas.
In the coming weeks the Lamby Cookiecutter will be updated to use Development Containers so folks with (or without) Codespaces can easily work with the project. The result will be something like this.
With Development Containers, so much docker compose boilerplate can be removed. Thanks in huge part to our newly released common & docker-in-docker Amazon Linux 2 features work. If you want to see an example of how this helps everyone including running Codespaces locally with VS Code, checkout our Crypteia Project's Development section. You can even use all this without VS Code & GitHub Codespaces. For example:
devcontainer build --workspace-folder . devcontainer up --workspace-folder . devcontainer run-user-commands --workspace-folder . devcontainer exec --workspace-folder . ./bin/setup devcontainer exec --workspace-folder . ./bin/test-local
So can Development Containers be used in your projects without the Lambda patterns above? Yes! Consider the following diagram that has a Platform Engineering team building base images.
These teams typically approach containers from the right to the left. Where base OS images are made into language specific images with variants for CI/CD. Just like SAM has build and runtime images. Technically for them "Runtime" is some container registry like Amazon ECR, but you get the idea.
At Custom Ink we are using our CircleCI images for our Kubernetes projects with Codespaces. The Microsoft team makes this easy since all of their features work with Ubuntu out of the box.
If your development stages look something like the image above. Please consider adopting Development Containers based on your CI/CD images and explore that big purple space by connecting your container value chain in a beautiful little circle. Thanks for reading!