
This is part of a series on the modern web stack, written from a WordPress developer’s seat for people who’ve built on the web for years and still hit stack terms they can’t define. The goal is literacy, enough that you can read any stack list and know what each piece does.
Each post has a 10-15 minute audio companion, generated with NotebookLM, for the gym or the commute.
Most WordPress developers have heard of Docker, opened a tutorial, recognized nothing, and closed the tab. Explanations tend to start with “containers are like lightweight virtual machines,” which doesn’t help if you’ve never run a virtual machine for development. The first command in every tutorial is docker run -it ubuntu bash, which comes with no context at all.
This is the explanation I’d have wanted years ago: what containers are, why people use them, what they do for WordPress work, and when to keep ignoring them.
What a Container Is
A container is a packaged unit of software that includes the code, the runtime (Node, PHP, Python), the system libraries, and the configuration needed to run that code. Running a container means telling Docker, or another container runtime, to start one of those packages. It boots in milliseconds, runs isolated from the rest of your system, and stops cleanly when you’re done.
Two pieces matter conceptually.
The image
The image is the package: a snapshot of a complete environment, with an OS layer, a runtime layer (such as node:20), and your application code on top. Images are immutable. You build one once, version it, and ship it.
The container
The container is a running instance of an image. You can run dozens from the same image at once, all isolated from each other. When one stops it disappears, and the image stays, ready to start another.
Dockerfiles and Compose files
A Dockerfile is a text file that describes how to build an image. Think of a server setup script that’s reproducible and versioned alongside the application code.
FROM node:20-alpine
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
CMD ["pnpm", "start"]
That file describes a Node.js app. Anyone with Docker installed can build it, get the same image, and run it, so “works on my machine” stops being an excuse.
A docker-compose.yml file describes a group of containers that run together. The classic example is a web app, a database, and a cache on one network, defined in one YAML file. docker compose up starts all three and docker compose down stops them and cleans up. The Compose docs cover the syntax.
The WordPress Analogue
A Docker container is to a server what a wp-env preset is to a development environment, except the same thing also runs in production.
If you’ve set up a fresh WordPress environment from scratch, you know the routine: install PHP at the right version, install MySQL, configure Nginx, set up the WordPress files, fix permissions, and hope nothing in your local OS conflicts. A container image already holds the right PHP version, MySQL, Nginx, and configuration. You start it, and the environment matches your colleague’s, staging, and production.
WordPress has tools for this, including wp-env, Local, and Lando. wp-env and Lando are abstractions over Docker. Once you understand Docker directly, you can build the same environments yourself, customize them precisely, and deploy them anywhere.
The Pieces of the Docker Ecosystem
The ecosystem has a few moving parts you’ll keep meeting.
Docker Desktop
Docker Desktop is the macOS and Windows installer that gives you the engine, the CLI, and a GUI. It’s free for personal use, and commercial use has needed a paid plan since 2022. Most developers use it locally and rarely in production.
Docker Engine
Docker Engine is the container runtime itself. It runs natively on Linux and virtualized on Mac and Windows. Production Linux servers typically run the engine without the desktop UI.
Docker Compose
Docker Compose orchestrates multi-container setups. Kubernetes takes over at scale in production, but Compose remains the right tool for local development and small deployments.
containerd, Podman, and Colima
containerd, Podman, and Colima are alternative runtimes that solve specific problems. Podman runs rootless, and Colima is a lighter Docker Desktop replacement on macOS. For most workflows the choice doesn’t matter, since the same images and commands work.
Kubernetes
Kubernetes runs containers at scale across many machines, a different conceptual level from Docker itself. It’s worth knowing it exists and rarely worth learning for a solo developer or small team.
Container registries
Registries are where you push images so your servers can pull them. Docker Hub is the default public one. AWS ECR and the GitHub Container Registry are common private options.
Buildpacks
Buildpacks build images without a Dockerfile. Heroku used them for years, and platforms like Fly.io and Railway often use them under the hood. They’re useful when you don’t want to write a Dockerfile.
For a default 2026 project, I’d run Docker Desktop locally (or Colima if you want to avoid the Docker Inc. license), Compose for multi-service local development, the GitHub Container Registry for images, and a managed platform that pulls from the registry. The hosting post covers where those platforms fit, and the serverless and edge post covers the alternative that skips containers.
What This Changes for WordPress People
Three practical wins once containers click.
Local development gets simpler. A docker-compose.yml that defines WordPress, MySQL, Nginx, and MailHog for testing email runs about 50 lines. Anyone who clones the repo runs docker compose up and has the full stack. It beats “install MAMP and configure these five things,” which is what most WordPress shops still do.
Staging and production match local. If production runs the same image as your laptop, “works on my machine but not in prod” mostly goes away. That’s the original Docker pitch, and it holds up.
Hybrid stacks deploy cleanly. A WordPress backend in one container and a Next.js frontend in another, both behind a reverse proxy, are defined in code and deployed identically across environments. The mental shift is from configuring servers to shipping containers that run anywhere. The headless WordPress post covers that pairing.
You don’t always need Docker. A personal WordPress blog on Kinsta can ignore it entirely, and so can a side project on Vercel. The value shows up when your environment has multiple services, custom dependencies, or production targets that need consistency.
Docker’s Rough Edges
A handful of traps.
File permissions on macOS and Windows
The Linux user inside a container often has UID 1000 by default, and your Mac user has a different UID. Files created inside containers can show up with wrong permissions on the host. Set USER correctly in your Dockerfile or use the right bind-mount flags.
Volumes vs bind mounts
Containers are ephemeral, so data you want to keep (a database file, uploaded media) needs a volume. Volumes are Docker-managed and bind mounts point at a specific host path. The distinction matters more in production than in development, and mixing them up loses your data on restart.
Image size
Naive Dockerfiles produce images over 1GB. Alpine-based base images, multi-stage builds, and a .dockerignore keep them small. Slow builds and large registry pulls compound at scale.
Networking
Containers talk to each other through Docker’s internal networking. Reaching a service on the host, such as your local MySQL, takes special configuration on macOS and Windows (host.docker.internal). It trips up everyone the first time.
Production isn’t Compose
Compose handles maybe three services on one machine. Production usually needs an orchestrator such as Kubernetes, Fly machines, Railway, or AWS ECS to handle scheduling, health checks, secrets, and restarts. Your Dockerfile transfers, and the orchestration around it changes.
Get Fluent With Docker
A few resources worth your time.
YouTube
Watch “Docker in 100 Seconds” by Fireship for orientation, then “Docker Tutorial for Beginners” by NetworkChuck (about an hour) for the real walkthrough. Bret Fisher’s “Docker Compose for Development” (about 30 minutes) covers the Compose workflow, the part most relevant to WordPress developers.
Docs
The official Docker docs have a solid “Get Started” guide, and the Compose docs are the reference for docker-compose.yml syntax. You’ll come back to them often. The Docker Curriculum by Prakhar Srivastav is a free walkthrough that goes deeper than the official docs and is well paced for building the mental model.
The next post moves from packaging to delivery: CI/CD, what GitHub Actions does, and why deploying by git push replaces FTP in modern projects.

Leave a Reply