If you’ve ever wrestled with XAMPP, MAMP, or even the popular LocalWP, you know the pain: bloated installs, PHP version conflicts, mystery permission errors, and environments that behave differently on every machine. In 2026, serious WordPress developers are moving to a smarter approach: a local WordPress development environment powered by Docker.
In this tutorial, we’ll spin up a fully containerized WordPress dev stack in under 10 minutes. You’ll get a clean, reproducible workflow with database setup, volume mounts for instant file edits, and live theme reloading. Let’s dive in.
Why Docker Beats XAMPP, MAMP and Even LocalWP
Tools like LocalWP and XAMPP are popular for a reason: they’re easy to click through. But they hide complexity that comes back to bite you when your production server doesn’t match your local setup. Docker fixes this by giving you the exact environment your live site runs on.
| Feature | Docker | LocalWP | XAMPP/MAMP |
|---|---|---|---|
| Reproducible across machines | Yes | Partial | No |
| Version control for environment | Yes (docker-compose.yml) | No | No |
| Mirror production stack | Yes | Limited | Rarely |
| Easy multi-site / multi-PHP | Yes | Yes | Painful |
| Resource footprint | Low | Medium | High |

What You’ll Need Before Starting
- Docker Desktop installed (Windows, macOS, or Linux)
- A code editor (VS Code, PhpStorm, etc.)
- Basic command line familiarity
- About 10 minutes of your time
That’s it. No PHP install. No MySQL install. No Apache. Docker handles everything.
Step 1: Create Your Project Folder
Open your terminal and create a clean folder for your project:
mkdir my-wp-site && cd my-wp-site
mkdir -p wp-content/themes wp-content/plugins
We pre-create the wp-content subfolders so we can mount our themes and plugins as volumes for live editing.
Step 2: Write the docker-compose.yml File
This single file defines your entire local WordPress development environment. Create a file named docker-compose.yml in your project root:
services:
db:
image: mariadb:11
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass
volumes:
- db_data:/var/lib/mysql
wordpress:
image: wordpress:6.7-php8.3-apache
depends_on:
- db
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppass
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DEBUG: 1
volumes:
- wp_data:/var/www/html
- ./wp-content/themes:/var/www/html/wp-content/themes
- ./wp-content/plugins:/var/www/html/wp-content/plugins
phpmyadmin:
image: phpmyadmin:latest
depends_on:
- db
ports:
- "8081:80"
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: rootpass
volumes:
db_data:
wp_data:
What’s happening here?
- db: A MariaDB container holding your WordPress database
- wordpress: WordPress with PHP 8.3 and Apache, mapped to
localhost:8080 - phpmyadmin: Optional GUI for the database at
localhost:8081 - Volume mounts: Your local
themesandpluginsfolders sync directly into the container, so any code change is reflected instantly

Step 3: Launch Your Environment
From your project folder, run:
docker compose up -d
Docker will pull the images and start three containers. Once finished, open your browser and go to:
- WordPress:
http://localhost:8080 - phpMyAdmin:
http://localhost:8081
You’ll be greeted by the WordPress installer. Set your title, admin user, and password. You’re live, locally.
Step 4: Enable Live Theme Reloading
Because your themes folder is mounted as a volume, every change to a PHP, CSS or JS file is immediate. For true live reloading in the browser, add BrowserSync to your theme workflow.
Inside your custom theme folder, initialize a Node project:
cd wp-content/themes/my-theme
npm init -y
npm install --save-dev browser-sync
Add this script to your package.json:
"scripts": {
"dev": "browser-sync start --proxy 'localhost:8080' --files '**/*.php, **/*.css, **/*.js'"
}
Then run:
npm run dev
BrowserSync opens a new tab (usually localhost:3000) that auto-refreshes the moment you save any theme file. Perfect for rapid theme development.
Step 5: Use WP-CLI Inside Docker
Need to run WP-CLI commands? You can execute them directly inside your container:
docker compose exec wordpress bash
# Inside the container:
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar && mv wp-cli.phar /usr/local/bin/wp
wp --info --allow-root
Or use the dedicated wordpress:cli image as a sidecar service in your compose file if you prefer.

Step 6: Daily Workflow Commands
| Action | Command |
|---|---|
| Start environment | docker compose up -d |
| Stop environment | docker compose down |
| View logs | docker compose logs -f wordpress |
| Reset everything | docker compose down -v |
| Enter container shell | docker compose exec wordpress bash |
Bonus: Sharing With Your Team
The real magic? Commit your docker-compose.yml to Git. Any teammate can clone the repo, run docker compose up -d, and have the identical development environment in minutes. No more “works on my machine” tickets.
Common Pitfalls and How to Fix Them
- Port already in use: Change
8080:80to8888:80if another service is blocking port 8080. - Permission errors on Linux: Run
sudo chown -R $USER:$USER wp-contenton your host folder. - Database connection refused: Wait a few seconds after first launch. MariaDB needs time to initialize.
- Slow file sync on Mac/Windows: Add
:cachedor:delegatedto volume mounts for performance.
FAQ
Is Docker better than LocalWP for WordPress development?
For solo bloggers, LocalWP is simpler. For developers, agencies, and teams who need reproducibility and parity with production, Docker wins every time. You can version your environment, share it via Git, and match server stacks exactly.
Do I need to know Docker deeply to use this setup?
No. The docker-compose.yml file in this guide is copy-paste ready. You only need to know three commands: up, down, and logs.
Can I run multiple WordPress sites at the same time?
Yes. Just create separate folders, each with its own docker-compose.yml, and assign different ports (e.g., 8080, 8082, 8084). They run in parallel without conflict.
How do I migrate my local Docker site to production?
Export your database with WP-CLI or phpMyAdmin, zip your wp-content folder, and upload both to your live server. Plugins like WP Migrate or All-in-One WP Migration also work flawlessly with this setup.
Does this work on Apple Silicon (M1/M2/M3) Macs?
Yes. The official WordPress and MariaDB images are multi-arch, so they run natively on ARM. No emulation tricks needed in 2026.
Final Thoughts
A Docker-based local WordPress development environment gives you something no point-and-click tool can: total control, perfect reproducibility, and a setup that mirrors your production server. Once you make the switch, you won’t go back to XAMPP or MAMP, and even LocalWP starts to feel limiting.
Save the compose file, commit it to your repo, and ship better WordPress sites faster. Happy coding.

