diff --git a/01-history-and-motivation/README.md b/01-history-and-motivation/README.md new file mode 100644 index 0000000..4368bce --- /dev/null +++ b/01-history-and-motivation/README.md @@ -0,0 +1,74 @@ +# History and Motivation + + + - [What is a container?](#what-is-a-container) + - [History of virtualization](#history-of-virtualization) + - [Bare Metal](#bare-metal) + - [Virtual Machines](#virtual-machines) + - [Containers](#containers) + - [Tradeoffs](#tradeoffs) + +--- + +## What is a container? + +A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application (https://www.docker.com/resources/what-container/). + +## History of virtualization + +### Bare Metal + +Before virtualization was invented, all programs ran directly on the host system. The terminology many people use for this is "bare metal". While that sounds fancy and scary, you are almost certainly familiar with running on bare metal because that is what you do whenever you install a program onto your laptop/desktop computer. + +![](./readme-assets/bare-metal.jpg) + +With a bare metal system, the operating system, binaries/libraries, and applications are installed and run directly onto the physical hardware. + +This is simple to understand and direct access to the hardware can be useful for specific configuration, but can lead to: +- Hellish dependency conflicts +- Low utilization efficiency +- Large blast radius +- Slow start up & shut down speed (minutes) +- Very slow provisioning & decommissioning (hours to days) + +--- + +### Virtual Machines + +Virtual machines use a system called a "hypervisor" that can carve up the host resources into multiple isolated virtual hardware configuration which you can then treat as their own systems (each with an OS, binaries/libraries, and applications). + +![](./readme-assets/virtual-machine.jpg) + +This helps improve upon some of the challenges presented by bare metal: + +- No dependency conflicts +- Better utilization efficiency +- Small blast radius +- Faster startup and shutdown (minutes) +- Faster provisioning & decommissioning (minutes) + +--- + +### Containers + +Containers are similar to virtual machines in that they provide an isolated environment for installing and configuring binaries/libraries, but rather than virtualizing at the hardware layer containers use native linux features (cgroups + namespaces) to provide that isolation while still sharing the same kernel. + +![](./readme-assets/container.jpg) + +This approach results in containers being more "lightweight" than virtual machines, but not providing the save level of isolation: + +- No dependency conflicts +- Even better utilization efficiency +- Small blast radius +- Even faster startup and shutdown (seconds) +- Even faster provisioning & decommissioning (seconds) +- Lightweight enough to use in development! + +--- + +### Tradeoffs + +![](./readme-assets/tradeoffs.jpg) + +***Note:*** There is much more nuance to β€œperformance” than this chart can capture. A VM or container doesn’t inherently sacrifice much performance relative to the bare metal it runs on, but being able to have more control over things like connected storage, physical proximity of the system relative to others it communicates with, specific hardware accelerators, etc… do enable performance tuning + diff --git a/01-history-and-motivation/readme-assets/bare-metal.jpg b/01-history-and-motivation/readme-assets/bare-metal.jpg new file mode 100644 index 0000000..9fed832 Binary files /dev/null and b/01-history-and-motivation/readme-assets/bare-metal.jpg differ diff --git a/01-history-and-motivation/readme-assets/container.jpg b/01-history-and-motivation/readme-assets/container.jpg new file mode 100644 index 0000000..eb703b5 Binary files /dev/null and b/01-history-and-motivation/readme-assets/container.jpg differ diff --git a/01-history-and-motivation/readme-assets/tradeoffs.jpg b/01-history-and-motivation/readme-assets/tradeoffs.jpg new file mode 100644 index 0000000..a149b19 Binary files /dev/null and b/01-history-and-motivation/readme-assets/tradeoffs.jpg differ diff --git a/01-history-and-motivation/readme-assets/virtual-machine.jpg b/01-history-and-motivation/readme-assets/virtual-machine.jpg new file mode 100644 index 0000000..06e10e5 Binary files /dev/null and b/01-history-and-motivation/readme-assets/virtual-machine.jpg differ diff --git a/04-using-3rd-party-containers/README.md b/04-using-3rd-party-containers/README.md index f648dc8..a0e1c9a 100644 --- a/04-using-3rd-party-containers/README.md +++ b/04-using-3rd-party-containers/README.md @@ -26,7 +26,7 @@ When we create a container from a container image, everything in the image is treated as read-only, and there is a new layer overlayed on top that is read/write. -![](./images/container-filesystem.jpg) +![](./readme-assets/container-filesystem.jpg) ### A. Installing Dependencies: @@ -106,7 +106,7 @@ The one exception to this rule is environment specific configuration (environmen Often, our applications produce data that we need to safely persist (e.g. database data, user uploaded data, etc...) even if the containers are destroyed and recreated. Luckily, Docker (and containers more generally) have a feature to handle this use case called `Volumes` and `mounts`! -![](./images/volumes.jpg) +![](./readme-assets/volumes.jpg) `Volumes` and `mounts` allow us to specify a location where data should persist beyond the lifecycle of a single container. The data can live in a location managed by Docker (`volume mount`), a location in your host filesystem (`bind mount`), or in memory (`tmpfs mount`, not pictured). diff --git a/04-using-3rd-party-containers/images/container-filesystem.jpg b/04-using-3rd-party-containers/readme-assets/container-filesystem.jpg similarity index 100% rename from 04-using-3rd-party-containers/images/container-filesystem.jpg rename to 04-using-3rd-party-containers/readme-assets/container-filesystem.jpg diff --git a/04-using-3rd-party-containers/images/volumes.jpg b/04-using-3rd-party-containers/readme-assets/volumes.jpg similarity index 100% rename from 04-using-3rd-party-containers/images/volumes.jpg rename to 04-using-3rd-party-containers/readme-assets/volumes.jpg diff --git a/06-building-container-images/README.md b/06-building-container-images/README.md index 7a8a848..df6da58 100644 --- a/06-building-container-images/README.md +++ b/06-building-container-images/README.md @@ -28,7 +28,36 @@ Types of improvments: 9) **Avoid assumptions:** Using commands like `EXPOSE ` make it clear to users how the image is intended to be used and avoids the need for them to make assumptions. 10) **Use multi-stage builds where sensible:** For some situations, multi-stage builds can vastly reduce the size of the final image and improve build times. Learn about and use multi-stage builds where appropriate. -All of these techniques are leveraged across the example applications in this repo. +In general, these techniques impact some combination of (1) build speed, (2) image security, and (3) developer clarity. The following summarizes these impacts: + +``` +Legend: + πŸ”’ Security + 🏎️ Build Speed + πŸ‘οΈ Clarity +``` +- Pin specific versions [πŸ”’ πŸ‘οΈ] + - Base images (either major+minor OR SHA256 hash) [πŸ”’ πŸ‘οΈ] + - System Dependencies [πŸ”’ πŸ‘οΈ] + - Application Dependencies [πŸ”’ πŸ‘οΈ] +- Use small + secure base images [πŸ”’ 🏎️] +- Protect the layer cache [🏎️ πŸ‘οΈ] + - Order commands by frequency of change [🏎️] + - COPY dependency requirements file β†’ install deps β†’ copy remaining source code [🏎️] + - Use cache mounts [🏎️] + - Use COPY --link [🏎️] + - Combine steps that are always linked (use heredocs to improve tidiness) [🏎️ πŸ‘οΈ] +- Be explicit [πŸ”’ πŸ‘οΈ] + - Set working directory with WORKDIR [πŸ‘οΈ] + - Indicate standard port with EXPOSE [πŸ‘οΈ] + - Set default environment variables with ENV [πŸ”’ πŸ‘οΈ] +- Avoid unnecessary files [πŸ”’ 🏎️ πŸ‘οΈ] + - Use .dockerignore [πŸ”’ 🏎️ πŸ‘οΈ] + - COPY specific files [πŸ”’ 🏎️ πŸ‘οΈ] +- Use non-root USER [πŸ”’] +- Install only production dependencies [πŸ”’ 🏎️ πŸ‘οΈ] +- Avoid leaking sensitive information [πŸ”’] +- Leverage multi-stage builds [πŸ”’ 🏎️] ## Additional Features