Running WordPress in Docker: Setup and Production Guide
Docker has become the standard way to package and deploy web applications, and WordPress is no exception. Running WordPress in a container gives you consistent environments across development, staging, and production, version-controlled infrastructure, and the ability to deploy on any container-capable platform. This tutorial walks through setting up WordPress in Docker and preparing it for production.
Prerequisites
You'll need:
- Docker and Docker Compose installed locally
- Basic familiarity with the command line
- A container registry or cloud platform for production deployment
Local Development with Docker Compose
Docker Compose lets you define a multi-container application in a single file. WordPress requires at minimum two containers: the WordPress PHP application and a MySQL or MariaDB database.
Create a docker-compose.yml in a new project directory:
version: '3.9'
services:
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppassword
volumes:
- db_data:/var/lib/mysql
wordpress:
image: wordpress:6.5-php8.3-apache
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppassword
volumes:
- wp_content:/var/www/html/wp-content
volumes:
db_data:
wp_content:Start the stack:
docker compose up -dNavigate to http://localhost:8080 and complete the WordPress installation wizard. Your database and uploaded media persist in named Docker volumes.
Understanding the Volume Strategy
The Docker WordPress image keeps the WordPress core files inside the container, which is fine — they're stateless and can be replaced by pulling a new image. However, two directories need to persist across container restarts and deployments:
- wp-content/ — Contains your themes, plugins, and uploaded media.
- The database — Handled by the
db_datavolume.
In the Compose file above, wp_content maps to /var/www/html/wp-content inside the container. This survives container recreation.
Writing a Production Dockerfile
The official WordPress image works for development, but production often requires customization: additional PHP extensions, custom php.ini values, or pre-installed plugins. Create a Dockerfile:
FROM wordpress:6.5-php8.3-apache
# Increase PHP memory limit for WooCommerce or heavy plugins
RUN echo "memory_limit = 256M" > /usr/local/etc/php/conf.d/custom.ini
RUN echo "upload_max_filesize = 64M" >> /usr/local/etc/php/conf.d/custom.ini
RUN echo "post_max_size = 64M" >> /usr/local/etc/php/conf.d/custom.ini
# Install Redis PHP extension for object caching
RUN pecl install redis && docker-php-ext-enable redis
# Copy a custom wp-config.php if needed
# COPY wp-config.php /var/www/html/wp-config.phpBuild and tag your image:
docker build -t my-wordpress:latest .Environment Variables for Configuration
Never hardcode credentials in your Dockerfile or docker-compose.yml. In production, pass sensitive values as environment variables injected by your deployment platform.
The WordPress Docker image respects these environment variables:
WORDPRESS_DB_HOSTWORDPRESS_DB_NAMEWORDPRESS_DB_USERWORDPRESS_DB_PASSWORDWORDPRESS_AUTH_KEY,WORDPRESS_SECURE_AUTH_KEY, and other salts
Generate secure salt values from the WordPress secret key API and inject them via your platform's secret management.
Deploying to a Cloud Container Platform
Once your image is built and pushed to a container registry, you can deploy it to any container-capable cloud platform. PandaStack supports Docker container deployments with GitHub integration — push your Dockerfile to a GitHub repository, connect it to PandaStack, and the platform builds and deploys your container.
For the database, use PandaStack's managed MySQL rather than running a database container yourself. Managed databases handle backups, failover, and scaling — concerns you don't want to manage inside a container.
Handling wp-content in Production
In a containerized production environment, wp-content presents a challenge: containers are ephemeral, but media uploads must persist. Options:
- 1Offload media to object storage (S3, GCS) using a plugin like WP Offload Media. The container stays stateless; media lives in durable object storage.
- 2Mount a persistent volume on your container platform. PandaStack and most Kubernetes-based platforms support persistent volume claims.
Option 1 is cleaner for scalability — if you run multiple container replicas, all instances share the same object storage backend without needing distributed filesystem mounts.
Health Checks
Add a Docker health check so your orchestrator knows when the container is ready:
HEALTHCHECK --interval=30s --timeout=5s --start-period=60s \
CMD curl -f http://localhost/ || exit 1Summary
Running WordPress in Docker standardizes your environment, makes deployments reproducible, and unlocks the full ecosystem of container platforms. Pair your containerized WordPress with managed databases and a platform like PandaStack for production-ready deployments with GitHub integration.
Explore the dashboard at [dashboard.pandastack.io](https://dashboard.pandastack.io) and the full documentation at [docs.pandastack.io](https://docs.pandastack.io).