FrankenWP is a specialized WordPress Docker image built on FrankenPHP, which is a PHP application server built on top of the Caddy web server. This combination offers several advantages:
- Single Docker image for WordPress that includes built-in distributed server caching
- Uses Souin & Caddy server for performance comparable to PHP-FPM + fastcgi
- Simplified deployment with a single container instead of separate web server and PHP containers
- Ability to mount server cache on multiple autoscaled servers
This guide will walk you through setting up FrankenWP on your own server using Docker Compose, including all necessary configuration options and client connection details.
Also see my article about FrankenPHP and using it under WSL2 on Windows as a development environment.
Prerequisites
- A server with Docker and Docker Compose installed
- Basic knowledge of Docker and Docker Compose
- Basic understanding of WordPress configuration
- Access to your server via SSH or other remote management tools
Setting Up the Docker Compose Environment
1. Create a Project Directory
First, create a directory for your FrankenWP project:
1 2 3 4 |
mkdir frankenwp-project cd frankenwp-project |
2. Create the Docker Compose File
Create a compose.yaml
file in your project directory:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
services: wordpress: image: stephenmiracle/frankenwp:latest restart: always ports: - "8094:80" # HTTP # - "80:80" # HTTP # - "443:443" # HTTPS # - "443:443/udp" # HTTP/3 environment: SERVER_NAME: ${SERVER_NAME:-:80} WORDPRESS_DB_HOST: ${DB_HOST:-db} WORDPRESS_DB_USER: ${DB_USER:-exampleuser} WORDPRESS_DB_PASSWORD: ${DB_PASSWORD:-examplepass} WORDPRESS_DB_NAME: ${DB_NAME:-exampledb} WORDPRESS_DEBUG: ${WP_DEBUG:-true} WORDPRESS_TABLE_PREFIX: ${DB_TABLE_PREFIX:-wp_} CACHE_AGE: ${CACHE_AGE:-8000} STATIC_CACHE_AGE: ${STATIC_CACHE_AGE:-8000} CADDY_GLOBAL_OPTIONS: | email myemail@sample.com auto_https disable_redirects debug # WORDPRESS_CONFIG_EXTRA: | # define('WP_SITEURL', ''); # define('WP_HOME', ''); volumes: - ./wp-content:/var/www/html/wp-content depends_on: - db tty: true db: image: mariadb:latest restart: always ports: - ${LOCAL_DB_PORT:-3309}:3306 environment: MYSQL_DATABASE: ${DB_NAME:-exampledb} MYSQL_USER: ${DB_USER:-exampleuser} MYSQL_PASSWORD: ${DB_PASSWORD:-examplepass} MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-examplepass} volumes: - wpdbv:/var/lib/mysql phpmyadmin: image: phpmyadmin/phpmyadmin restart: always ports: - ${LOCAL_PHPMYADMIN_PORT:-8096}:80 environment: PMA_HOST: db MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-examplepass} depends_on: - db volumes: wpdbv: |
This Docker Compose file sets up three services:
- wordpress: The FrankenWP container running WordPress on FrankenPHP
- db: A MariaDB database container
- phpmyadmin: A phpMyAdmin container for database management
3. Create the Environment File
Create a .env
file in your project directory to customize the environment variables:
1 2 3 4 5 6 7 8 9 10 11 12 |
SERVER_NAME=:8094 WP_DEBUG=0 WORDPRESS_DB_HOST=db WORDPRESS_DB_USER=exampleuser WORDPRESS_DB_PASSWORD=examplepass WORDPRESS_DB_NAME=exampledb WORDPRESS_TABLE_PREFIX=wp_ DB_ROOT_PASSWORD=examplepass LOCAL_DB_PORT=3306 LOCAL_PHPMYADMIN_PORT=8096 |
4. Create the wp-content Directory
Create a wp-content
directory in your project folder:
1 2 3 |
mkdir wp-content |
This directory will be mounted into the WordPress container and will store themes, plugins, and uploads.
Configuration Options
Environment Variables
The FrankenWP Docker Compose setup uses several environment variables that can be customized in your .env
file:
Variable | Description | Default Value |
---|---|---|
SERVER_NAME | Caddy server name | :80 |
WP_DEBUG | Enable WordPress debug mode | true |
WORDPRESS_DB_HOST | Database host | db |
WORDPRESS_DB_USER | Database user | exampleuser |
WORDPRESS_DB_PASSWORD | Database password | examplepass |
WORDPRESS_DB_NAME | Database name | exampledb |
WORDPRESS_TABLE_PREFIX | WordPress table prefix | wp_ |
DB_ROOT_PASSWORD | MySQL root password | examplepass |
LOCAL_DB_PORT | Local port for MySQL | 3309 |
LOCAL_PHPMYADMIN_PORT | Local port for phpMyAdmin | 8096 |
CACHE_AGE | Cache age in seconds | 8000 |
STATIC_CACHE_AGE | Static cache age in seconds | 8000 |
Caddy Server Configuration
The FrankenWP image uses Caddy server, which is configured through the CADDY_GLOBAL_OPTIONS
environment variable in the Docker Compose file. This variable allows you to set various Caddy options:
1 2 3 4 5 6 |
CADDY_GLOBAL_OPTIONS: | email myemail@sample.com auto_https disable_redirects debug |
Common Caddy options include:
email
: Email address for Let’s Encrypt certificateauto_https
: HTTPS configuration (disable_redirects turns off HTTP to HTTPS redirects)debug
: Enable debug modefrankenphp
: FrankenPHP configuration options
For production use, you should enable HTTPS by updating the CADDY_GLOBAL_OPTIONS
and uncommenting the HTTPS port mapping in the Docker Compose file.
WordPress Configuration
Additional WordPress configuration can be added using the WORDPRESS_CONFIG_EXTRA
environment variable:
1 2 3 4 5 |
WORDPRESS_CONFIG_EXTRA: | define('WP_SITEURL', 'https://example.com'); define('WP_HOME', 'https://example.com'); |
Running the FrankenWP Server
1. Start the Containers
From your project directory, run:
1 2 3 |
docker compose up -d |
This will start all three containers in detached mode.
2. Check the Status
Verify that all containers are running properly:
1 2 3 |
docker compose ps |
3. Access WordPress
Once the containers are running, you can access WordPress at:
- WordPress: http://your-server-ip:8094
- phpMyAdmin: http://your-server-ip:8096
4. Complete the WordPress Setup
Visit http://your-server-ip:8094 in your browser to complete the WordPress installation process.
Connecting to the Server
1. Browser Connection
To connect to your FrankenWP server, simply point your web browser to:
- http://your-server-ip:8094 (or whichever port you configured)
2. WordPress Admin
Once WordPress is set up, you can access the admin panel at:
- http://your-server-ip:8094/wp-admin
3. Domain Configuration
For production use, you’ll want to use a domain name instead of an IP address. Update your DNS settings to point your domain to your server’s IP address.
Then, update the Docker Compose file to use your domain:
1 2 3 4 5 |
environment: SERVER_NAME: yourdomain.com # Other environment variables... |
And uncomment the HTTPS port mappings:
1 2 3 4 5 6 7 |
ports: # - "8094:80" # HTTP (development) - "80:80" # HTTP - "443:443" # HTTPS - "443:443/udp" # HTTP/3 |
Update the Caddy configuration to enable automatic HTTPS:
1 2 3 4 5 |
CADDY_GLOBAL_OPTIONS: | email youremail@yourdomain.com # Remove or comment out auto_https disable_redirects |
Advanced Configuration
Customizing FrankenPHP Settings
FrankenPHP settings can be customized in the Caddy configuration. For example, to adjust PHP worker threads:
1 2 3 4 5 6 7 8 9 10 |
CADDY_GLOBAL_OPTIONS: | email youremail@yourdomain.com frankenphp { num_threads 16 # Sets the number of PHP threads to start max_threads 32 # Limits the number of additional PHP threads php_ini upload_max_filesize 100M # Set PHP configuration php_ini post_max_size 100M } |
Custom Caddyfile
For more complex Caddy configurations, you can mount a custom Caddyfile into the container:
1 2 3 4 5 6 7 8 |
services: wordpress: # Other settings... volumes: - ./wp-content:/var/www/html/wp-content - ./Caddyfile:/etc/caddy/Caddyfile |
SSL/TLS Configuration
Caddy automatically handles SSL/TLS certificates using Let’s Encrypt when you configure a domain name. In production, enable HTTPS by updating your Docker Compose file:
1 2 3 4 5 6 7 8 9 10 |
ports: - "80:80" - "443:443" - "443:443/udp" # HTTP/3 environment: SERVER_NAME: yourdomain.com CADDY_GLOBAL_OPTIONS: | email youremail@yourdomain.com |