A satellite project of labs.iximiuz.com - an indie learning platform to master Linux, Containers, and Kubernetes the hands-on way 🚀
Building container images can be both an easy and a hard problem. Building just an image is usually as straightforward as replicating your local app build steps in a Dockerfile’s To help you become a true container image build master, I prepared a learning path that starts with creating and pushing your very first container image and goes through analyzing the contents of the image to picking an optimal base and learning how to spot and troubleshoot runtime problems caused by flawed image composition. Warming up: Docker 101To get started, let’s build and push a very simple container image: Challenge: Build and Publish a Container Image With Docker Know what you’ve builtOne of the critical but often overlooked skills when working with container images is the ability to introspect their contents and know exactly what’s inside. Yes, images are often represented as a sequence of overlaid folders, but when extracted, the insides look like a regular folder, which often contains a typical Linux distro root filesystem (rootfs).
In the How To Extract Container Image Filesystem Using Docker tutorial, you’ll learn about different ways to extract a container image filesystem using standard Docker commands (spoiler: it’s not that simple if you want to inspect the truly unmodified original rootfs). When you're done with the tutorial, don't forget to check your skills by solving this (slightly more complex) challenge: Extract the Filesystem of a Container Image. Choosing an optimal baseOnce you are familiar with the main The A Deeper Look into Node.js Docker Images tutorial explores various Node.js base image options and serves as an example of how to do proper due diligence when choosing a base image.
While the tutorial is focused on Node.js images, it touches on an important image composition problem that reoccurs in many other container images, such as Multi-stage buildsChoosing the right base container image can be particularly tricky if you want to both build and run your application in Docker. The tools (e.g., compilers and linters) and packages (e.g., testing frameworks, code generators) needed to build a typical application differ significantly from what’s required to run it in production. For a production image to be efficient and secure, it must contain only an absolutely minimal set of OS-level packages and runtime dependencies, whereas compiler toolchains tend to be huge and riddled with CVEs. Luckily, with multi-stage builds, you don’t need to pick a single base image to satisfy both build and runtime requirements. Learn more about this vital technique in the How to Build Smaller Container Images: Docker Multi-Stage Builds tutorial (with practical examples for Node.js, Go, Rust, and Java).
Practice time: Containerizing Node.js applicationsContainer images are often poorly structured because Dockerfiles are treated as no man’s land:
This disconnect is understandable - it’s a lot of cross-functional knowledge to juggle! To solve these Node.js challenges, you might need to consult framework documentation on producing standalone builds:
While Next.js and Nuxt support “standalone” builds, other frameworks can use different build practices. For instance, in Svelte, project dependencies must be copied from the build stage to the production stage, along with the app bundle itself. While doing this, it’s crucial to avoid copying dev-time dependencies by mistake. This challenge highlights the importance of truly understanding stack-specific nuances in addition to Docker best build practices: And don't forget to use multi-stage builds while building these Node.js images! What does the smallest possible base image look like?Building container images In the Building Container Images FROM Scratch: 6 Pitfalls That Are Often Overlooked tutorial, you’ll learn about the pitfalls of building images
Practice time: Dockerize a statically linked Go applicationApply the knowledge from the previous tutorial to containerize this simple Go app: Build a Production-Ready Go Container Image: A Statically Linked Application. Troubleshoot a containerized Go applicationSolve this challenge to understand how missing components in a Distroless as a better runtime baseIf Learn more here: What's Inside Distroless Container Images: Taking a Closer Look.
Practice time: Dockerize a dynamically linked Go applicationUse your newfound knowledge to containerize this more complex Go app: Build a Production-Ready Go Container Image: A Dynamically Linked Application. Troubleshoot another containerized Go applicationAnother service failing due to a bad containerization attempt - can you fix it? Apply your knowledge of distroless images to rebuild the container: Pick the Right Distroless Base Image For Your Application. Ideal image rootfs isn't everythingA flawed Dockerfile can cause more than just missing files or packages. Solve this challenge to explore another common issue—broken signal propagation: Ensure a Graceful Termination for a Container With an Entrypoint Script.
Know your application stackThe same issue (broken graceful termination) can arise from different root causes. This challenge highlights how a lack of knowledge about your app stack or Linux basics (e.g., sub-shells and signal propagation) can lead to production issues: Ensure a Graceful Termination for a Containerized Node.js Application.
Container Image Security 101Last but not least! Poor image composition (unnecessary dependencies) or lack of proper maintenance (missing security patches) can lead to extra work for your security team - or worse, production breaches. Learn how to scan your images for vulnerabilities and patch affected packages in this challenge by a long-time Docker engineer, Felipe Cruz: Docker Scout: Remediating CVEs in a Container Image. Need an expert opinion? Reach out!Learning how to build optimal container images takes a lot of time and effort. While I encourage you to go through all the above materials to acquire this skill yourself, it's totally fine if you and your team need some expert help today, and I've got some great news. Kyle Quest and I teamed up to:
If it sounds like something your team would benefit from, fill in the form at gooddockerfiles.com. Limited-time offer!
Happy building! Cheers Ivan |
A satellite project of labs.iximiuz.com - an indie learning platform to master Linux, Containers, and Kubernetes the hands-on way 🚀