Table of Contents

Copyright

Brief Table of Contents

Table of Contents

Praise for the first edition

Foreword

Preface

Acknowledgments

About this book

About the authors

About the cover illustration

Chapter 1. Welcome to Docker

1.1. What is Docker?

1.1.1. “Hello, World”

1.1.2. Containers

1.1.3. Containers are not virtualization

1.1.4. Running software in containers for isolation

1.1.5. Shipping containers

1.2. What problems does Docker solve?

1.2.1. Getting organized

1.2.2. Improving portability

1.2.3. Protecting your computer

1.3. Why is Docker important?

1.4. Where and when to use Docker

1.5. Docker in the larger ecosystem

1.6. Getting help with the Docker command line

Summary

1. Process isolation and environment-independent computing

Chapter 2. Running software in containers

2.1. Controlling containers: Building a website monitor

2.1.1. Creating and starting a new container

2.1.2. Running interactive containers

2.1.3. Listing, stopping, restarting, and viewing output of containers

2.2. Solved problems and the PID namespace

2.3. Eliminating metaconflicts: Building a website farm

2.3.1. Flexible container identification

2.3.2. Container state and dependencies

2.4. Building environment-agnostic systems

2.4.1. Read-only filesystems

2.4.2. Environment variable injection

2.5. Building durable containers

2.5.1. Automatically restarting containers

2.5.2. Using PID 1 and init systems

2.6. Cleaning up

Summary

Chapter 3. Software installation simplified

3.1. Identifying software

3.1.1. What is a named repository?

3.1.2. Using tags

3.2. Finding and installing software

3.2.1. Working with Docker registries from the command line

3.2.2. Using alternative registries

3.2.3. Working with images as files

3.2.4. Installing from a Dockerfile

3.2.5. Using Docker Hub from the website

3.3. Installation files and isolation

3.3.1. Image layers in action

3.3.2. Layer relationships

3.3.3. Container filesystem abstraction and isolation

3.3.4. Benefits of this toolset and filesystem structure

3.3.5. Weaknesses of union filesystems

Summary

Chapter 4. Working with storage and volumes

4.1. File trees and mount points

4.2. Bind mounts

4.3. In-memory storage

4.4. Docker volumes

4.4.1. Volumes provide container-independent data management

4.4.2. Using volumes with a NoSQL database

4.5. Shared mount points and sharing files

4.5.1. Anonymous volumes and the volumes-from flag

4.6. Cleaning up volumes

4.7. Advanced storage with volume plugins

Summary

Chapter 5. Single-host networking

5.1. Networking background (for beginners)

5.1.1. Basics: Protocols, interfaces, and ports

5.1.2. Bigger picture: Networks, NAT, and port forwarding

5.2. Docker container networking

5.2.1. Creating a user-defined bridge network

5.2.2. Exploring a bridge network

5.2.3. Beyond bridge networks

5.3. Special container networks: host and none

5.4. Handling inbound traffic with NodePort publishing

5.5. Container networking caveats and customizations

5.5.1. No firewalls or network policies

5.5.2. Custom DNS configuration

5.5.3. Externalizing network management

Summary

Chapter 6. Limiting risk with resource controls

6.1. Setting resource allowances

6.1.1. Memory limits

6.1.2. CPU

6.1.3. Access to devices

6.2. Sharing memory

6.2.1. Sharing IPC primitives between containers

6.3. Understanding users

6.3.1. Working with the run-as user

6.3.2. Users and volumes

6.3.3. Introduction to the Linux user namespace and UID remapping

6.4. Adjusting OS feature access with capabilities

6.5. Running a container with full privileges

6.6. Strengthening containers with enhanced tools

6.6.1. Specifying additional security options

6.7. Building use-case-appropriate containers

6.7.1. Applications

6.7.2. High-level system services

6.7.3. Low-level system services

Summary

2. Packaging software for distribution

Chapter 7. Packaging software in images

7.1. Building Docker images from a container

7.1.1. Packaging “Hello, World”

7.1.2. Preparing packaging for Git

7.1.3. Reviewing filesystem changes

7.1.4. Committing a new image

7.1.5. Configuring image attributes

7.2. Going deep on Docker images and layers

7.2.1. Exploring union filesystems

7.2.2. Reintroducing images, layers, repositories, and tags

7.2.3. Managing image size and layer limits

7.3. Exporting and importing flat filesystems

7.4. Versioning best practices

Summary

Chapter 8. Building images automatically with Dockerfiles

8.1. Packaging Git with a Dockerfile

8.2. A Dockerfile primer

8.2.1. Metadata instructions

8.2.2. Filesystem instructions

8.3. Injecting downstream build-time behavior

8.4. Creating maintainable Dockerfiles

8.5. Using startup scripts and multiprocess containers

8.5.1. Environmental preconditions validation

8.5.2. Initialization processes

8.5.3. The purpose and use of health checks

8.6. Building hardened application images

8.6.1. Content-addressable image identifiers

8.6.2. User permissions

8.6.3. SUID and SGID permissions

Summary

Chapter 9. Public and private software distribution

9.1. Choosing a distribution method

9.1.1. A distribution spectrum

9.1.2. Selection criteria

9.2. Publishing with hosted registries

9.2.1. Publishing with public repositories: “Hello World!” via Docker Hub

9.2.2. Private hosted repositories

9.3. Introducing private registries

9.3.1. Using the registry image

9.3.2. Consuming images from your registry

9.4. Manual image publishing and distribution

9.4.1. A sample distribution infrastructure using FTP

9.5. Image source-distribution workflows

9.5.1. Distributing a project with Dockerfile on GitHub

Summary

Chapter 10. Image pipelines

10.1. Goals of an image build pipeline

10.2. Patterns for building images

10.2.1. All-in-one images

10.2.2. Separate build and runtime images

10.2.3. Variations of runtime image via multi-stage builds

10.3. Record metadata at image build time

10.3.1. Orchestrating the build with make

10.4. Testing images in a build pipeline

10.5. Patterns for tagging images

10.5.1. Background

10.5.2. Continuous delivery with unique tags

10.5.3. Configuration image per deployment stage

10.5.4. Semantic versioning

Summary

3. Higher-level abstractions and orchestration

Chapter 11. Services with Docker and Compose

11.1. A service “Hello World!”

11.1.1. Automated resurrection and replication

11.1.2. Automated rollout

11.1.3. Service health and rollback

11.2. Declarative service environments with Compose V3

11.2.1. A YAML primer

11.2.2. Collections of services with Compose V3

11.3. Stateful services and preserving data

11.4. Load balancing, service discovery, and networks with Compose

Summary

Chapter 12. First-class configuration abstractions

12.1. Configuration distribution and management

12.2. Separating application and configuration

12.2.1. Working with the config resource

12.2.2. Deploying the application

12.2.3. Managing config resources directly

12.3. Secrets—A special kind of configuration

12.3.1. Using Docker secrets

Summary

Chapter 13. Orchestrating services on a cluster of Docker hosts with Swarm

13.1. Clustering with Docker Swarm

13.1.1. Introducing Docker Swarm mode

13.1.2. Deploying a Swarm cluster

13.2. Deploying an application to a Swarm cluster

13.2.1. Introducing Docker Swarm cluster resource types

13.2.2. Defining an application and its dependencies by using Docker services

13.2.3. Deploying the application

13.3. Communicating with services running on a Swarm cluster

13.3.1. Routing client requests to services by using the Swarm routing mesh

13.3.2. Working with overlay networks

13.3.3. Discovering services on an overlay network

13.3.4. Isolating service-to-service communication with overlay networks

13.3.5. Load balancing

13.4. Placing service tasks on the cluster

13.4.1. Replicating services

13.4.2. Constraining where tasks run

13.4.3. Using global services for one task per node

13.4.4. Deploying real applications onto real clusters

Summary

 Docker running three containers on a Linux system

Index

List of Figures

List of Tables