docker.recipes

WordPress Bedrock Professional

intermediate

Modern WordPress stack with Bedrock, Composer, Redis object cache, and security hardening.

Overview

PHP-FPM (FastCGI Process Manager) is a scalable PHP processor that handles web requests through a pool of worker processes, offering superior performance and resource management compared to traditional mod_php implementations. This professional WordPress stack combines PHP-FPM with NGINX for high-performance web serving, while Bedrock modernizes WordPress development through Composer dependency management, environment-specific configurations, and enhanced security practices that separate WordPress core files from custom application code. The integration of MariaDB provides robust database performance with enhanced storage engines and clustering capabilities, while Redis delivers sub-millisecond object caching that dramatically reduces database queries and improves page load times. NGINX handles SSL termination, static file serving, and request routing with its event-driven architecture, while MailHog captures outgoing emails during development to prevent accidental sends to real users. This configuration serves development teams, digital agencies, and WordPress professionals who require modern development workflows, enhanced security postures, and enterprise-grade performance. The Bedrock framework's structured approach to WordPress development, combined with Redis object caching and MariaDB's advanced features, creates a foundation suitable for high-traffic WordPress sites that demand both developer productivity and operational reliability.

Key Features

  • Bedrock framework with Composer-managed WordPress core and plugin dependencies
  • PHP-FPM process pool management with configurable worker processes and memory limits
  • Redis object cache integration reducing database queries by 80-95% on cached content
  • MariaDB 11 with Aria storage engine and thread pool connection handling
  • NGINX FastCGI caching with configurable cache zones and purging capabilities
  • Environment-specific configuration through .env files separating development and production settings
  • MailHog email interception preventing accidental email sends during development
  • Structured WordPress installation with web root separation and enhanced security headers

Common Use Cases

  • 1WordPress agencies managing multiple client sites with consistent deployment workflows
  • 2High-traffic WordPress sites requiring object caching and database optimization
  • 3Development teams needing modern PHP dependency management and version control
  • 4WordPress multisite networks with centralized plugin and theme management
  • 5E-commerce WordPress sites with WooCommerce requiring enhanced performance
  • 6Enterprise WordPress deployments with strict security and compliance requirements
  • 7WordPress development environments with email testing and debugging capabilities

Prerequisites

  • Docker Engine 20.10+ and Docker Compose V2 for container orchestration
  • Minimum 2GB RAM (4GB recommended) for MariaDB, Redis, and PHP-FPM processes
  • Composer knowledge for managing Bedrock dependencies and WordPress plugins
  • Basic understanding of WordPress file structure and wp-config.php alternatives
  • Familiarity with environment variables and .env file configuration
  • Available ports 80, 443, 1025, and 8025 for web and mail services

For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms

docker-compose.yml

docker-compose.yml
1services:
2 nginx:
3 image: nginx:alpine
4 ports:
5 - "80:80"
6 - "443:443"
7 volumes:
8 - ./nginx.conf:/etc/nginx/nginx.conf:ro
9 - ./certs:/etc/nginx/certs:ro
10 - wordpress_data:/var/www/html
11 depends_on:
12 - php
13 networks:
14 - wp-net
15 restart: unless-stopped
16
17 php:
18 build:
19 context: .
20 dockerfile: Dockerfile.php
21 volumes:
22 - wordpress_data:/var/www/html
23 - ./php.ini:/usr/local/etc/php/conf.d/custom.ini:ro
24 environment:
25 DB_HOST: mariadb
26 DB_NAME: ${MYSQL_DATABASE}
27 DB_USER: ${MYSQL_USER}
28 DB_PASSWORD: ${MYSQL_PASSWORD}
29 WP_ENV: development
30 WP_HOME: http://localhost
31 WP_SITEURL: http://localhost/wp
32 REDIS_HOST: redis
33 depends_on:
34 mariadb:
35 condition: service_healthy
36 redis:
37 condition: service_started
38 networks:
39 - wp-net
40 restart: unless-stopped
41
42 mariadb:
43 image: mariadb:11
44 environment:
45 MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
46 MYSQL_DATABASE: ${MYSQL_DATABASE}
47 MYSQL_USER: ${MYSQL_USER}
48 MYSQL_PASSWORD: ${MYSQL_PASSWORD}
49 volumes:
50 - mariadb_data:/var/lib/mysql
51 healthcheck:
52 test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
53 interval: 10s
54 timeout: 5s
55 retries: 5
56 networks:
57 - wp-net
58 restart: unless-stopped
59
60 redis:
61 image: redis:7-alpine
62 volumes:
63 - redis_data:/data
64 networks:
65 - wp-net
66 restart: unless-stopped
67
68 mailhog:
69 image: mailhog/mailhog:latest
70 ports:
71 - "1025:1025"
72 - "8025:8025"
73 networks:
74 - wp-net
75 restart: unless-stopped
76
77volumes:
78 wordpress_data:
79 mariadb_data:
80 redis_data:
81
82networks:
83 wp-net:
84 driver: bridge

.env Template

.env
1# Database Configuration
2MYSQL_ROOT_PASSWORD=secure_root_password
3MYSQL_DATABASE=wordpress
4MYSQL_USER=wordpress
5MYSQL_PASSWORD=secure_mysql_password
6
7# WordPress Salts (generate at https://roots.io/salts.html)
8AUTH_KEY=
9SECURE_AUTH_KEY=
10LOGGED_IN_KEY=
11NONCE_KEY=
12AUTH_SALT=
13SECURE_AUTH_SALT=
14LOGGED_IN_SALT=
15NONCE_SALT=

Usage Notes

  1. 1Create Dockerfile.php with Bedrock dependencies
  2. 2Install Bedrock: composer create-project roots/bedrock
  3. 3MailHog for email testing at http://localhost:8025
  4. 4Redis Object Cache plugin recommended

Individual Services(5 services)

Copy individual services to mix and match with your existing compose files.

nginx
nginx:
  image: nginx:alpine
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf:ro
    - ./certs:/etc/nginx/certs:ro
    - wordpress_data:/var/www/html
  depends_on:
    - php
  networks:
    - wp-net
  restart: unless-stopped
php
php:
  build:
    context: .
    dockerfile: Dockerfile.php
  volumes:
    - wordpress_data:/var/www/html
    - ./php.ini:/usr/local/etc/php/conf.d/custom.ini:ro
  environment:
    DB_HOST: mariadb
    DB_NAME: ${MYSQL_DATABASE}
    DB_USER: ${MYSQL_USER}
    DB_PASSWORD: ${MYSQL_PASSWORD}
    WP_ENV: development
    WP_HOME: http://localhost
    WP_SITEURL: http://localhost/wp
    REDIS_HOST: redis
  depends_on:
    mariadb:
      condition: service_healthy
    redis:
      condition: service_started
  networks:
    - wp-net
  restart: unless-stopped
mariadb
mariadb:
  image: mariadb:11
  environment:
    MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    MYSQL_DATABASE: ${MYSQL_DATABASE}
    MYSQL_USER: ${MYSQL_USER}
    MYSQL_PASSWORD: ${MYSQL_PASSWORD}
  volumes:
    - mariadb_data:/var/lib/mysql
  healthcheck:
    test:
      - CMD
      - healthcheck.sh
      - "--connect"
      - "--innodb_initialized"
    interval: 10s
    timeout: 5s
    retries: 5
  networks:
    - wp-net
  restart: unless-stopped
redis
redis:
  image: redis:7-alpine
  volumes:
    - redis_data:/data
  networks:
    - wp-net
  restart: unless-stopped
mailhog
mailhog:
  image: mailhog/mailhog:latest
  ports:
    - "1025:1025"
    - "8025:8025"
  networks:
    - wp-net
  restart: unless-stopped

Quick Start

terminal
1# 1. Create the compose file
2cat > docker-compose.yml << 'EOF'
3services:
4 nginx:
5 image: nginx:alpine
6 ports:
7 - "80:80"
8 - "443:443"
9 volumes:
10 - ./nginx.conf:/etc/nginx/nginx.conf:ro
11 - ./certs:/etc/nginx/certs:ro
12 - wordpress_data:/var/www/html
13 depends_on:
14 - php
15 networks:
16 - wp-net
17 restart: unless-stopped
18
19 php:
20 build:
21 context: .
22 dockerfile: Dockerfile.php
23 volumes:
24 - wordpress_data:/var/www/html
25 - ./php.ini:/usr/local/etc/php/conf.d/custom.ini:ro
26 environment:
27 DB_HOST: mariadb
28 DB_NAME: ${MYSQL_DATABASE}
29 DB_USER: ${MYSQL_USER}
30 DB_PASSWORD: ${MYSQL_PASSWORD}
31 WP_ENV: development
32 WP_HOME: http://localhost
33 WP_SITEURL: http://localhost/wp
34 REDIS_HOST: redis
35 depends_on:
36 mariadb:
37 condition: service_healthy
38 redis:
39 condition: service_started
40 networks:
41 - wp-net
42 restart: unless-stopped
43
44 mariadb:
45 image: mariadb:11
46 environment:
47 MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
48 MYSQL_DATABASE: ${MYSQL_DATABASE}
49 MYSQL_USER: ${MYSQL_USER}
50 MYSQL_PASSWORD: ${MYSQL_PASSWORD}
51 volumes:
52 - mariadb_data:/var/lib/mysql
53 healthcheck:
54 test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
55 interval: 10s
56 timeout: 5s
57 retries: 5
58 networks:
59 - wp-net
60 restart: unless-stopped
61
62 redis:
63 image: redis:7-alpine
64 volumes:
65 - redis_data:/data
66 networks:
67 - wp-net
68 restart: unless-stopped
69
70 mailhog:
71 image: mailhog/mailhog:latest
72 ports:
73 - "1025:1025"
74 - "8025:8025"
75 networks:
76 - wp-net
77 restart: unless-stopped
78
79volumes:
80 wordpress_data:
81 mariadb_data:
82 redis_data:
83
84networks:
85 wp-net:
86 driver: bridge
87EOF
88
89# 2. Create the .env file
90cat > .env << 'EOF'
91# Database Configuration
92MYSQL_ROOT_PASSWORD=secure_root_password
93MYSQL_DATABASE=wordpress
94MYSQL_USER=wordpress
95MYSQL_PASSWORD=secure_mysql_password
96
97# WordPress Salts (generate at https://roots.io/salts.html)
98AUTH_KEY=
99SECURE_AUTH_KEY=
100LOGGED_IN_KEY=
101NONCE_KEY=
102AUTH_SALT=
103SECURE_AUTH_SALT=
104LOGGED_IN_SALT=
105NONCE_SALT=
106EOF
107
108# 3. Start the services
109docker compose up -d
110
111# 4. View logs
112docker compose logs -f

One-Liner

Run this command to download and set up the recipe in one step:

terminal
1curl -fsSL https://docker.recipes/api/recipes/wordpress-bedrock/run | bash

Troubleshooting

  • PHP-FPM 'pool seems busy' errors: Increase pm.max_children and pm.max_requests in php-fpm pool configuration
  • Bedrock 'vendor directory not found' error: Run 'composer install' in the WordPress root directory before starting containers
  • Redis connection refused from PHP: Verify Redis service is running and REDIS_HOST environment variable matches service name
  • MariaDB 'Access denied for user' errors: Check MYSQL_USER and MYSQL_PASSWORD environment variables match between PHP and MariaDB services
  • NGINX 502 Bad Gateway errors: Ensure PHP-FPM container is healthy and FastCGI pass configuration points to correct upstream
  • MailHog not capturing emails: Verify PHP mail configuration uses mailhog:1025 as SMTP server in php.ini

Community Notes

Loading...
Loading notes...

Download Recipe Kit

Get all files in a ready-to-deploy package

Includes docker-compose.yml, .env template, README, and license

Ad Space