Fixing HTTP 500 Errors When Setting Up a Local WordPress Development Environment with Docker

DevOpsDevOps Tools

YOUR COSMETIC CARE STARTS HERE

Find the Best Cosmetic Hospitals

Trusted • Curated • Easy

Looking for the right place for a cosmetic procedure? Explore top cosmetic hospitals in one place and choose with confidence.

“Small steps lead to big changes — today is a perfect day to begin.”

Explore Cosmetic Hospitals Compare hospitals, services & options quickly.

✓ Shortlist providers • ✓ Review options • ✓ Take the next step with confidence

Setting up a local WordPress development environment with Docker gives you full control over the stack — but it also means you have to wire up Nginx, PHP-FPM, and MariaDB yourself. A common stumbling block is an HTTP 500 error that appears silently during the WordPress installation wizard, specifically when submitting database credentials at /wp-admin/setup-config.php?step=1. This article walks through a working Docker Compose configuration and explains why the 500 error occurs and how to fix it.

The Target Stack

The setup uses three containers managed by Docker Compose:

  • nginx — reverse proxy and static file server
  • phpfpm — PHP-FPM process manager that executes WordPress PHP files
  • mariadb — MySQL-compatible database server

docker-compose.yml

Below is the Docker Compose file that describes the three services. Note that the wordpress directory is bind-mounted into both the nginx and phpfpm containers so they share the same document root.

version: '3'

services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./wordpress:/var/www/html
      - ./config/nginx:/etc/nginx/conf.d
      - ./logs/nginx:/var/log/nginx
    depends_on:
      - phpfpm
    restart: always

  mariadb:
    image: mariadb:latest
    ports:
      - "3306:3306"
    volumes:
      - ./data/db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: password
    restart: always

  phpfpm:
    image: php:fpm
    ports:
      - "9000:9000"
    volumes:
      - ./wordpress:/var/www/html
    depends_on:
      - mariadb
    restart: alwaysCode language: JavaScript (javascript)

Nginx wordpress.conf

Place the following file at ./config/nginx/wordpress.conf. It passes all .php requests to the phpfpm container over FastCGI on port 9000, and uses the standard WordPress try_files rewrite rule.

server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass phpfpm:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        include fastcgi_params;
    }
}Code language: PHP (php)

The HTTP 500 Error During WordPress Setup

After running docker-compose up you can reach http://127.0.0.1/wp-admin/setup-config.php and start the WordPress installation. The first step loads fine. However, after submitting the database credentials form at step 1, the browser displays a blank page and the Nginx access log records a 500 response:

172.18.0.1 - - [24/Jun/2017:07:25:54 +0000] "POST /wp-admin/setup-config.php?step=2 HTTP/1.1" 500 5 "http://127.0.0.1/wp-admin/setup-config.php?step=1" "Mozilla/5.0 (X11; Linux x86_64; rv:54.0) Gecko/20100101 Firefox/54.0"Code language: JavaScript (javascript)

No corresponding entry appears in the Nginx error log, which means Nginx itself completed the FastCGI transaction successfully — the 500 status was generated by PHP, not Nginx.

Root Cause: Missing MySQL Extension in the Official php:fpm Image

The official php:fpm Docker image ships with a minimal set of PHP extensions. Critically, it does not include the mysqli or pdo_mysql extensions that WordPress requires to connect to a database. When WordPress’s setup wizard attempts to write wp-config.php and test the database connection, PHP throws a fatal error internally, resulting in the blank 500 response.

Because PHP fatal errors at this stage are caught before WordPress’s error handler is fully initialised, no useful message reaches the browser or the Nginx error log. You may see something useful in the PHP-FPM log, which you can check with:

docker-compose logs phpfpm

Fix 1: Build a Custom PHP-FPM Image with MySQL Extensions

Create a Dockerfile alongside your docker-compose.yml that extends the official image and installs the required extensions:

FROM php:fpm

RUN docker-php-ext-install mysqli pdo pdo_mysqlCode language: CSS (css)

Then update the phpfpm service in your docker-compose.yml to build from this Dockerfile instead of pulling the image directly:

  phpfpm:
    build: .
    ports:
      - "9000:9000"
    volumes:
      - ./wordpress:/var/www/html
    depends_on:
      - mariadb
    restart: alwaysCode language: JavaScript (javascript)

Rebuild and restart the stack:

docker-compose up --build

Fix 2: Use the Official wordpress:fpm Image

If you do not need a fully custom PHP build, the simplest alternative is to replace the php:fpm image with the official wordpress:fpm image. This image is purpose-built for WordPress and already includes mysqli, pdo_mysql, and other extensions WordPress depends on:

  phpfpm:
    image: wordpress:fpm
    ports:
      - "9000:9000"
    volumes:
      - ./wordpress:/var/www/html
    environment:
      WORDPRESS_DB_HOST: mariadb:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: password
    depends_on:
      - mariadb
    restart: alwaysCode language: JavaScript (javascript)

The wordpress:fpm image also auto-generates wp-config.php from the environment variables above, which eliminates the need to complete the setup wizard at all.

Additional Troubleshooting Steps

Enable PHP Error Logging

Add the following to your custom Dockerfile or mount a custom php.ini to expose PHP errors during development:

RUN echo "error_reporting = E_ALL" >> /usr/local/etc/php/php.ini \
 && echo "display_errors = On" >> /usr/local/etc/php/php.ini \
 && echo "log_errors = On" >> /usr/local/etc/php/php.iniCode language: JavaScript (javascript)

Never enable display_errors in a production environment.

Verify Database Connectivity

WordPress must connect to the database using the service name as the hostname, not localhost or 127.0.0.1. In the Docker Compose network, the correct hostname for the database is mariadb (matching the service name). Set the database host to mariadb in the WordPress setup wizard or in wp-config.php.

Check File Permissions

WordPress needs write access to the document root to create wp-config.php. If the ./wordpress directory on the host is owned by root or has restrictive permissions, the PHP-FPM process (which typically runs as www-data) cannot write the file, producing a 500 error. Fix ownership with:

sudo chown -R 33:33 ./wordpress   # 33 is the UID for www-data on Debian-based imagesCode language: PHP (php)

Timing: MariaDB May Not Be Ready

Docker Compose’s depends_on only waits for a container to start, not for the service inside it to be ready to accept connections. MariaDB can take several seconds to initialise on first run. If PHP-FPM tries to connect before MariaDB is ready, the connection will fail and WordPress will return a 500. Solutions include:

  • Waiting a few seconds after docker-compose up before loading the setup wizard.
  • Using a health-check and condition: service_healthy in Compose v3.x+ to delay the phpfpm container until MariaDB is accepting connections.
  • Using a startup script with a wait-for-it or similar utility.

Summary

The HTTP 500 error during WordPress setup with a custom Docker Compose stack almost always traces back to one of three causes: missing PHP MySQL extensions in the php:fpm base image, using localhost instead of the MariaDB service name as the database host, or file permission problems on the WordPress directory. Installing mysqli and pdo_mysql via docker-php-ext-install — or switching to the official wordpress:fpm image — resolves the most common case.

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x