Jean Galea

AI, Investing, Health, and Building Businesses

  • Start Here
  • Guides
    • Beginner’s Guide to Investing
    • Cryptocurrencies
    • Stocks
    • P2P Lending
    • Real Estate
  • Blog
  • My Story
  • Projects
  • Community
  • AI Consultancy
  • Search

Docker for WordPress Developers

Published: June 16, 2026Leave a Comment

Shipping containers stacked at a port

This is part of an ongoing series I am writing as I work my way through the modern web stack from a WordPress developer’s perspective. The series is aimed at WordPress veterans who, like me, have built things on the web for years and feel quietly behind the curve. The goal is broad literacy, not deep mastery. By the end you should be able to read any modern stack list and know what each piece is doing.

Each post comes with an audio companion (10-15 minutes, generated via NotebookLM) for gym or commute listening. Press play below if that suits you better than reading.

Hook

Docker has been around long enough that most WordPress developers have heard of it, opened a tutorial, recognised nothing, and quietly closed the tab. It does not help that Docker explanations always start with “containers are like lightweight virtual machines,” which is true but useless if you have never run a virtual machine for development. It does not help that the first command in every tutorial is docker run -it ubuntu bash, which is a sentence that contains no helpful context.

This module is the Docker explanation a WordPress developer should have been handed years ago. What containers actually are, why anyone uses them, what value they bring to WordPress work specifically, and when you should keep ignoring them.

Core Concept

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. When you “run a container,” you tell Docker (or another container runtime) to start one of those packages. It boots in milliseconds, runs in isolation from the rest of your system, and stops cleanly when you are done with it.

The two pieces that matter conceptually:

The image is the package. It is a snapshot of a complete environment: an OS layer, a runtime layer (e.g., node:20), and your application code layered on top. Images are immutable. You build them once, version them, and ship them.

The container is a running instance of an image. You can run dozens of containers from the same image simultaneously, all isolated from each other. When a container stops, it disappears; the image is still there, ready to start another container.

A Dockerfile is a text file that describes how to build an image. It is roughly equivalent to a setup script for a server, but 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 Dockerfile describes a Node.js app. Anyone with Docker installed can build it, get the exact same image, and run it. No “works on my machine” problems.

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, all connected on the same network, defined in one YAML file. Run docker compose up and all three start. Run docker compose down and they stop and clean up.

The WordPress Analogue

Mental model: A Docker container is to a server what a phpenv or wp-env preset is to a development environment, except the same thing also runs in production.

If you have ever set up a fresh WordPress development environment from scratch, you know the pain: install PHP at the right version, install MySQL, configure Nginx, set up the WordPress files, configure permissions, and pray nothing in your local OS conflicts. Containers solve this. The container image already contains the right PHP version, MySQL, Nginx, and configuration. You start the container, and the environment is identical to your colleague’s, to staging, and to production.

WordPress itself has tools for this — wp-env, Local by Flywheel, Lando — but they are abstractions over Docker. Once you understand Docker directly, you can build the same environments yourself, customise them precisely, and deploy them anywhere.

The Landscape

The Docker ecosystem has a few moving parts you will keep meeting.

Docker Desktop. The macOS / Windows installer that gives you the Docker engine, CLI, and a GUI. Free for personal use; commercial use requires a paid plan since 2022. Most developers use it locally; production rarely.

Docker Engine. The actual container runtime. Runs on Linux natively, virtualised on Mac and Windows. Production Linux servers typically run just the engine without the desktop UI.

Docker Compose. The tool for orchestrating multi-container setups locally. Replaced by Kubernetes for production at scale, but Compose remains the right tool for local development and small deployments.

Containerd / Podman / Colima. Alternative container runtimes that solve specific problems (Podman runs rootless; Colima is a lighter Docker Desktop replacement on macOS). For most workflows the choice does not matter; the same images and commands work.

Kubernetes. The orchestration layer that runs containers at scale across many machines. A different conceptual level from Docker itself. Worth knowing exists; rarely worth learning for a solo developer or small team.

Container registries. Where you push images so they can be pulled by your servers. Docker Hub is the default public registry. AWS ECR, GitHub Container Registry, and Cloudflare’s registry are the common private alternatives.

Buildpacks. A different way of building images that skips the Dockerfile entirely. Heroku used these for years; modern platforms (Fly.io, Railway) often use them under the hood. Useful when you do not want to write a Dockerfile.

For a default 2026 project: Docker Desktop locally (or Colima if you avoid the Docker Inc license), Docker Compose for multi-service local dev, GitHub Container Registry for storing images, deploy via a managed platform that consumes the registry.

What This Changes for WordPress People

Three practical wins once you internalise containers.

The first is local development gets simpler. A docker-compose.yml file that defines WordPress + MySQL + Nginx + Mailhog (for testing emails) is maybe 50 lines. Anyone who clones the repo runs docker compose up and has the full stack running locally. No “install MAMP and configure these five things.” This is genuinely better than the workflow most WordPress shops use.

The second is staging and production environments match local. If your production server runs the same Docker image as your laptop, “works on my machine but not in prod” goes away. This is the original Docker pitch and it still holds up.

The third is hybrid stacks deploy cleanly. A WordPress backend in one container, a Next.js frontend in another, both behind a reverse proxy: all defined in code, deployed identically across environments. The mental shift is from “configure servers” to “ship containers that run anywhere.”

You do not always need Docker. For a personal WordPress blog on Kinsta, ignore Docker entirely. For a side project on Vercel, ignore Docker. The value shows up when your environment has multiple services, custom dependencies, or production targets that need consistency.

Watch Out

A handful of traps.

File permission weirdness on macOS and Windows. The Linux user inside a container often has UID 1000 by default. Your Mac user has a different UID. Files created inside containers can show up with wrong permissions on the host. The fix is to set USER correctly in your Dockerfile or use the right bind-mount flags.

Volumes vs bind mounts. Containers are ephemeral; if you want data to persist (a database file, uploaded media), it needs to be on a volume. The distinction between volumes (Docker-managed) and bind mounts (a specific host path) matters more in production than in dev. Get them confused and your data disappears on restart.

Image size grows quickly. Naive Dockerfiles produce 1GB+ images. Use Alpine-based base images, multi-stage builds, and .dockerignore to keep images small. Slow builds and large registry pulls compound at scale.

Networking is its own subject. Containers can talk to each other through Docker’s internal networking. Connecting from a container to a service on the host (your local MySQL, for example) requires special configuration on macOS and Windows (host.docker.internal). This catches everyone the first time.

Production Docker is not Docker Compose. Local development with Compose scales to maybe three services on one machine. Production usually needs an orchestrator (Kubernetes, Fly machines, Railway, AWS ECS) that handles scheduling, health checks, secrets, and restarts. The shape of your Dockerfile transfers; the orchestration around it changes.

Going Deeper

If you want to develop real Docker fluency, a few resources worth your time.

YouTube, gym or commute friendly:

  • “Docker in 100 Seconds” by Fireship, then “Docker Tutorial for Beginners” by NetworkChuck (~1 hour). Orientation, then the real walkthrough.
  • “Docker Compose for Development” by Bret Fisher (~30 min). The Compose workflow specifically; this is the part most relevant to WordPress devs.

Official docs worth bookmarking:

  • Docker official docs. The “Get Started” guide is solid. Skim the rest.
  • Docker Compose docs. The reference for docker-compose.yml syntax. You will refer back to this often.
  • The Docker Curriculum by Prakhar Srivastav. A free walkthrough that goes deeper than the official docs and is well-paced for someone who wants to actually internalise the model.

Next post in the series moves from packaging to delivery: CI/CD, what GitHub Actions actually does, and why “deploy by git push” replaces FTP in modern projects.

Related

Docker container engine logo — the container platform that powers tools like wp-env, DDEV, and DevKinsta for WordPress development
Local WP vs Docker: When to Use Each for WordPress Development
Developer workspace with a colorful code editor on a screen lit by ambient blue and red lighting
The Complete Guide to Local WordPress Development and Testing
Modern Web Stack for WordPress Developers
Serverless and Edge Functions, Finally Explained
What’s Beyond WordPress?
wordpress replacement
Is There a WordPress Replacement in 2026? I Went Looking

Filed under: General, Modern Web Stack for WordPress Developers

Part 11 of 16 · Modern Web Stack for WordPress Developers

← PreviousServerless and Edge Functions, Finally ExplainedUp next · Jun 19CI/CD: Goodbye FTP, Hello GitHub Actions
All 16 modules
  1. Why Modern Web Feels Alien to WordPress Devs
  2. JavaScript and TypeScript for PHP People
  3. React, in WordPress Terms
  4. Next.js: The WordPress of React
  5. When NOT to Use Next.js
  6. Beyond Shared MySQL: Cloud Databases for WordPress Developers
  7. From WPDB to Drizzle, Prisma, and Kysely
  8. Auth in 2026: What Replaced wp_users
  9. Hosting Beyond Kinsta: Vercel, Fly, Railway, Cloudflare, and Friends
  10. Serverless and Edge Functions, Finally Explained
  11. Docker for WordPress Developers
  12. CI/CD: Goodbye FTP, Hello GitHub Actions Jun 19
  13. Observability When You Can't Just SSH In Jun 23
  14. Tailwind, shadcn/ui, and the New Design-System Meta
  15. Headless WordPress: The Bridge Jun 30
  16. How the Pieces Wire Up: A Modern Stack Integration Tour Jul 3

About Jean Galea

I build things on the internet and write about AI, investing, health, and how to live well. Founder of AgentVania and the Good Life Collective.

Leave a Reply Cancel reply

Thanks for choosing to leave a comment. Please keep in mind that all comments are moderated according to our comment policy, and your email address will NOT be published. Please Do NOT use keywords or links in the name field.

Latest Padel Match

Jean Galea

Investor | Dad | Global Citizen | Athlete

Follow @jeangalea

  • My Padel Journey
  • Affiliate Disclaimer
  • Cookies
  • Contact

Copyright © 2006 - 2026