
Containers are one of the most significant developments in modern IT.
We cover what they are at a high level, and explore the four key properties that make them so useful: portability, efficiency, isolation, and scalability.
A common question from newcomers — are containers just lightweight VMs?
We clear up this confusion by comparing containers and virtual machines side by side, covering how they differ in architecture and use case.
We go a level deeper and look at what containers actually are under the hood — how they use the host OS kernel rather than running their own, and what that means in practice.
Before starting our containers, we need somewhere to run them.
We walk through the options for setting up a lab environment, covering container engines and what you need to follow along with the rest of the course.
A look at the kinds of real-world services you can deploy as containers, from home lab tools to production workloads.
This sets the scene for what you'll be able to build by the end of the course.
Time to run your first container.
We verify the Docker engine is running, then use the command line to pull and start a container from scratch, walking through exactly what happens at each step.
Images and containers are related but different things.
We clarify the distinction and explore how that relationship works in practice.
When Docker pulls an image, where does it come from?
This video explains registries, how images are identified using tags, and how Docker Hub fits into the picture.
We expand on the basics by pulling and running a second container, introducing the docker pull command and exploring more of the options available when starting containers.
Containers are isolated by default, which means accessing their services requires some extra steps.
We look at how to expose container ports so they can be reached from a web browser.
Containers pass through several states: created, running, paused, stopped, and removed.
This video walks through each stage of the lifecycle and the commands used to move between them.
Images take up storage space.
We look at how to list, inspect, and clean up images on the local system using docker image ls, docker system df, and related commands.
Sometimes you need to get inside a running container to inspect or troubleshoot it.
We cover how to attach to a container's shell, including handling containers that use different shell types.
Connecting to a shell isn't always the best troubleshooting approach.
We deploy a busybox container and explore how to access container logs using Docker's built-in logging commands.
A quick tour of the Docker Desktop GUI and how it maps to the CLI commands we've been using.
We cover what it can and can't do, so you know when the command line is still the right tool.
A look at Docker's three-layer architecture: The client, the host, and the registry.
This solidifies the concepts covered so far and build a strong foundation before moving on.
Not all container storage works the same way.
We introduce the two categories — persistent storage (survives container removal) and non-persistent storage (lost when the container is removed) — and when to use each.
Volumes are Docker's recommended approach to persistent storage.
We create and manage volumes using the CLI, attach them to containers, and explore how Docker handles the underlying storage.
A bind mount maps a specific file or directory on the host directly into a container.
We look at how they differ from volumes, how to configure them, and the use cases where they make more sense.
An introduction to Docker's networking model.
We cover the difference between internal and external container networking, and provide a map of the network drivers we'll be exploring in this section.
Two of Docker's simpler network modes.
The host network shares the host's network stack directly with the container, while the none driver removes network access entirely.
We cover when each is appropriate.
The default Docker network type.
We explore how bridge networks create an isolated internal network, how containers communicate within it, and how to create custom bridge networks.
MACVLAN gives each container its own MAC address and IP on the physical network, making containers appear as independent devices.
We cover the setup, use cases, and limitations.
An evolution of MACVLAN that operates without assigning unique MAC addresses.
We cover both Layer 2 and Layer 3 modes, and explain the scenarios where IPVLAN is the better choice.
A side-by-side comparison of the network drivers covered in this section — bridge, MACVLAN, and IPVLAN — including a feature matrix to help you choose the right driver for your needs.
Until now we've only used pre-built images.
This video introduces the section and explains what we'll learn: How to create and customise our own images using Dockerfiles, without needing to write any application code.
Images are built from layers, and each layer is defined by an instruction in a Dockerfile.
We introduce the Dockerfile format, cover the most common instructions, and write our first one.
Docker caches layers to speed up builds and reduce bandwidth.
We look at how the caching system works, when cache is invalidated, and how to write Dockerfiles that take full advantage of it.
The entrypoint is the process that runs when a container starts.
We dig into how ENTRYPOINT and CMD work, the difference between them, and how to configure them correctly in a Dockerfile.
Docker images support metadata in the form of labels, and instructions like EXPOSE that communicate intent.
We cover how to add and read this information and why it matters.
Containers support environment variables that are isolated from the host.
We cover how to define them at build time and runtime, and why care is needed to avoid baking sensitive values into an image.
Security can't be an afterthought when building images.
This video covers the key risks — including sensitive data exposure and large attack surfaces — and the practices to address them early.
Multistage builds split the image-building process into stages, so build tools and intermediate files don't end up in the final image.
We walk through the concept and build a practical example.
With our own custom images built, we look at how to store and share them using registries.
We cover the main registry types — cloud/public, private cloud, and self-hosted — and when to use each.
Public and private repositories serve different purposes, and the difference isn't always obvious.
We clear up the distinction and explain how visibility settings work within registries like Docker Hub.
You can run your own registry as a container.
We deploy Docker's official registry image, configure it for local use, and push and pull images to and from it.
A walkthrough of creating a repository on Docker Hub, tagging an image, and pushing it to the registry, so your images are available anywhere you need them.
Most real-world applications involve more than one container.
This video introduces the challenge of managing multiple containers together and sets up the case for Docker Compose.
Docker Compose files are written in YAML.
Before writing our first one, we cover the basics of YAML syntax — indentation, key-value pairs, lists, and nesting — so the format makes sense.
We write our first Compose file, deploying a single NGINX container to learn the structure.
We then bring it up with docker compose up and explore the key commands for managing it.
We extend our Compose file to a real multi-container application. A web app with a PostgreSQL database backend.
This involves adding environment variables, volumes, and dependencies between services.
Managing environment variables in Compose files requires care.
We cover how to use .env files to keep sensitive values out of your Compose file and avoid committing secrets to version control.
Compose can build custom images as part of the deployment process, removing the need for a separate build step. We configure the build key and deploy a custom app directly from source.
Docker Desktop doesn't cover all of Docker's features, and Docker Engine has no GUI at all.
Portainer fills that gap. It's a third-party web-based management interface that works with Docker Engine and more.
A hands-on walkthrough of the Portainer interface. We connect it to a Docker environment and use it to manage containers, images, volumes, and networks through the GUI.
In Portainer, multi-container apps are deployed as stacks — the equivalent of Docker Compose.
We deploy a stack through the GUI and see how it compares to the command-line approach.
By default, a container can consume as many host resources as it wants.
We explain why that's a problem in production and introduce cgroups, the Linux feature Docker uses to enforce limits.
A practical guide to setting CPU, memory, disk I/O, and GPU limits on containers.
We run through the relevant Docker flags and see how limits are applied and verified.
Hardware isn't the only resource to consider.
We look at OS-level limits including process limits, ulimits, and swap memory, and discuss why services like databases are particularly sensitive to swap usage.
Security is critical at every layer of a container deployment.
This video maps out the attack surface, from custom images to running containers to the host OS, and previews the topics covered in this section.
Two goals guide secure image building: avoid leaking sensitive information, and reduce the attack surface.
We cover the key Dockerfile practices that help achieve both.
Containers don't need to run as root.
We look at how to configure user permissions in containers, and how Linux Capabilities allow us to grant only the specific privileges a container needs.
Container security is only part of the picture.
We cover the OS-level hardening measures that protect the Docker host itself, including patch management, firewall rules, and least-privilege access.
Docker Scout is Docker's built-in vulnerability scanner.
We run it against an image to identify known CVEs in its packages. This is particularly useful when working with third-party base images.
Snyk is a third-party security tool with a broader focus than Docker Scout.
We use it to scan images, application code, and infrastructure-as-code for vulnerabilities, using the free tier.
Docker Bench for Security runs automated checks against the CIS Docker Benchmark. This is a set of best-practice security recommendations.
We run it as a container and interpret the results.
The final piece of the security puzzle is network traffic.
We look at how to protect data in transit between containers, and between containers and the outside world.
Whether you've never heard of a container before or you've run a few Docker commands without really understanding what's happening under the hood, this course takes you from the very beginning to deploying a full stack of real-world services.
You'll start with the fundamentals — what containers are, how they compare to virtual machines, and how Docker works under the hood. From there, you'll work through every major building block: storage, networking, custom image creation, registries, Docker Compose, and more. Every concept is reinforced with hands-on labs, so you're not just watching — you're building.
By the end of the course, you won't just understand Docker in theory. You'll have deployed a working stack of real services including a DNS server with PiHole, uptime monitoring, cloud storage with Nextcloud, network monitoring, infrastructure documentation with NetBox, and full observability with Prometheus and Grafana. You'll secure everything with a Traefik reverse proxy, a password manager with VaultWarden, and a WireGuard VPN.
Topics covered include containers and Docker fundamentals, running and managing containers and images, persistent storage with volumes and bind mounts, networking (bridge, MACVLAN, IPVLAN, host, and none), building custom images with Dockerfiles, multi-container applications with Docker Compose, managing containers with Portainer, resource limits, and container security with Docker Scout, Snyk, and Docker Bench.
No prior experience with Docker or containers is required. If you're comfortable using a computer and have a basic understanding of how networks work, you have everything you need to get started. For the hands-on labs, you'll need either a physical workstation running Linux (nothing fancy) or the ability to run a Linux virtual machine.