Why Dockerize WordPress with Redis?
If you’ve ever struggled with upgrading PHP on a VPS only to have your website crash with a 500 error, Docker is your lifesaver. Traditional LAMP/LEMP setups are prone to errors if library versions mismatch. Docker packages everything into containers, ensuring that your dev and production environments are 100% consistent.
However, running just WordPress and MySQL isn’t enough. As traffic grows, the database will soon become a bottleneck. In practice, adding Redis as an Object Cache can reduce database response times from hundreds of milliseconds to just a few. Redis stores query results in RAM, allowing MariaDB’s CPU to breathe much easier.
Don’t wait until your site slows down to optimize. Build a solid structure from day one.
Project Directory Structure
Organized file management helps you avoid trouble when backing up or migrating servers. I usually separate code, data, and configuration clearly.
my-wordpress-site/
├── docker-compose.yml
├── .env
├── wordpress_data/
└── mariadb_data/
Setting Up a “Battle-Tested” Docker Compose File
I have now fully switched to Docker Compose v2. Instead of using the old docker-compose up command, the new syntax is docker compose up. V2 handles resources more smoothly and is significantly faster.
Below is the configuration file I usually use for real-world projects. I chose MariaDB 10.11 because it consumes less RAM than MySQL while offering slightly better query performance in containerized environments.
services:
db:
image: mariadb:10.11
container_name: wp_mariadb
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- ./mariadb_data:/var/lib/mysql
networks:
- wp_network
redis:
image: redis:7-alpine
container_name: wp_redis
restart: always
networks:
- wp_network
wordpress:
depends_on:
- db
- redis
image: wordpress:latest
container_name: wp_app
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
WORDPRESS_DB_NAME: ${DB_NAME}
WORDPRESS_CONFIG_EXTRA: |
define('WP_REDIS_HOST', 'redis');
define('WP_REDIS_PORT', 6379);
define('WP_CACHE', true);
volumes:
- ./wordpress_data:/var/www/html
networks:
- wp_network
networks:
wp_network:
driver: bridge
Key Points to Note:
- WORDPRESS_CONFIG_EXTRA: This is a great feature of the official WordPress image. It automatically inserts the Redis configuration into the
wp-config.phpfile without you having to open and edit it manually. - Isolated Network: The
wp_networkhelps containers communicate internally. The database doesn’t need to expose ports externally, preventing hackers from scanning port 3306. - Alpine Image: The
redis:7-alpineversion is only a few dozen MBs, helping to maximize disk space savings.
Managing Environment Variables with a .env File
Never hardcode passwords in your compose file if you plan to push code to GitHub. Create a .env file in the same directory to store sensitive parameters:
DB_ROOT_PASSWORD=super_strong_root_password
DB_NAME=wordpress_db
DB_USER=wp_admin
DB_PASSWORD=user_password
Activating Redis in the WordPress Dashboard
After running docker compose up -d, your site will be online at port 8080. However, Redis won’t start working automatically. You need to follow 3 more steps:
- Log in to wp-admin.
- Find and install the Redis Object Cache plugin.
- Go to Settings -> Redis and click “Enable Object Cache”.
Once you see the “Connected” status, it means Redis has started receiving cache. You will notice a significant improvement in page load speed.
Practical Optimization and Security Tips
1. Resource Limits
WordPress can “eat up” all server RAM if constantly scanned by bots. Limit resources directly in the compose file. 512MB of RAM is a reasonable amount for a stable personal blog.
deploy:
resources:
limits:
cpus: '0.50'
memory: 512M
2. Handling Permission Errors
If you can’t upload images, it’s likely due to a UID mismatch. On Linux, run the command chown -R 33:33 wordpress_data. This command gives the www-data user inside the container full write permissions.
3. Backup Strategy
Don’t rely entirely on Docker volumes. You should schedule a cronjob to dump the database daily. A compact .sql file will be your lifesaver if the server encounters hardware issues.
Conclusion
Combining MariaDB and Redis into a Docker stack makes WordPress run smoother and easier to manage. Leveraging WORDPRESS_CONFIG_EXTRA is the fastest way to automate everything. Good luck building a high-load, stable system!

