Foreword

The widespread technical evolution happening all around us is centered on a seemingly simple tool: the container. Something designed to be small and lightweight is having a tremendous impact on software development across all industries, all in such a short span of time.

But containerization is not new, and it wasn’t new in 2013 when Docker was first introduced. However, in the days before Docker, containerization was barely a blip on the radar of most software professionals; even the low-level concepts behind containers were generally understood only by those equipped with a deep knowledge of the Linux kernel, or by those working at some of the tech giants like Sun or Google. Windows developers and system administrators were generally left out in the cold. Nowadays, it’s hard to have a conversation about any software application without a mention of Docker. So how did we arrive here, and where are we going?

We no longer use Docker because it is novel, or for the sake of the technology itself, but rather because it accelerates development cycles, reduces infrastructure costs and overhead, helps onboard new developers more quickly, and even lowers the wall between development and operations teams. Windows users can now reap the benefits of Docker, too, thanks to the work from Microsoft, Docker, and countless open source software (OSS) contributors.

For all of its benefits, however, Docker isn’t always a simple tool. Truly understanding Docker is necessary in order to build and operate cloud-native applications—that is, applications that are scalable, highly available, and run on managed cloud infrastructures. Achieving this resiliency and scalability requires relying on containerization and eventually container orchestration technologies such as Kubernetes. In addition to these container tools, cloud-native applications are generally built with service-oriented or microservice architectures.

I’m often asked if Docker is replacing virtual machines (VMs), if microservices are a requirement, or if companies should forget about Docker now that serverless patterns are becoming more popular. The answer is always no! Tools in the cloud-native ecosystem are additive, not exclusive. Docker and VMs are not competing with one another, and instead should be used together to achieve maximum benefit. Serverless patterns are most powerful when they are used with containers, and I would argue that serverless wouldn’t have pushed to the forefront if ephemeral, lightweight containers didn’t enable them to do so. Microservices aren’t a prerequisite for containers either, though you may find that you’ll be able to reap more benefits when your architecture allows your services to be smaller, too.

Using Docker allows developers to expand their operational responsibilities and take more ownership of what they build. It can remove silos in your organization by making details like dependencies a responsibility of the development team, not solely the operations team. It also forces teams to create better artifacts that can serve as interesting points of documentation: a Dockerfile and docker-compose.yml file can take the role of an operating manual for the project. Developers who are getting started on your team or jumping into an open source project can become productive quickly so long as those files exist. In years past, getting a development environment running was often a multiday task, but now we can replace this with simple, repeatable workflow: install Docker, clone the repository, and get running with docker-compose up.

Similar to the cloud-native ecosystem being additive, a lot of Docker’s own tools are additive, and mastering the basics will only help you be more successful later on. In this book, pay particular attention to Chapter 4, which covers container images, including the most important piece of your project: the Dockerfile. This file, along with other images you may download directly from an image registry, will serve as the basis for your application. Every other operational layer, like container orchestration, depends on you first having your application code packaged inside of an image via a Dockerfile. You’ll learn that any application code can be packaged in a container image, regardless of age, framework, language, or architectural pattern.

In this book, Sean and Karl have shared their extensive collective knowledge in an attempt to equip you with a broad theoretical and tactical understanding of Docker and its ecosystem in order to help you succeed in your journey to containerization. While Docker can help simplify and optimize your development practices, it’s a rich tool with several layers of complexity. Sean and Karl have carefully crafted this book to focus on what’s important, and to help you get productive quickly while still understanding the important fundamentals.

Soak up the knowledge and experience they’ve shared with you on these pages, and keep this book around for reference—you’ll be glad you did.