Resolving the "Error Establishing a Database Connection" in WordPress running via Docker Compose typically requires verifying environment variables, ensuring network connectivity between containers, and implementing health checks to guarantee the database service is fully ready before WordPress attempts to connect. Misconfigured credentials or premature startup sequences are the most common culprits.
Verifying Environment Variables and Credentials
The most frequent cause of this error is a mismatch between the credentials defined in yourdocker-compose.yml file and those expected by the MySQL or MariaDB container. WordPress relies on four specific environment variables to establish its initial connection: WORDPRESS_DB_HOST, WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD, and WORDPRESS_DB_NAME. If any of these values are incorrect, even by a single character, the application will fail to authenticate with the database server.
You should inspect your docker-compose.yml file and ensure that the environment section under the WordPress service matches the configuration of the database service exactly. For instance, if your database service uses an image like mariadb:latest, it likely initializes with a root password set via the MARIADB_ROOT_PASSWORD variable. While WordPress typically connects using a dedicated user rather than root, both users must exist within the database instance.
It is also critical to check for trailing spaces or hidden characters in your YAML file. YAML is sensitive to indentation and whitespace. A simple copy-paste error from a documentation site might introduce invisible characters that break the string value. You can verify the actual values being passed to the container by running docker compose config in your project directory. This command renders the final resolved configuration, allowing you to see if any variables have been overridden or malformed during the parsing process. If you are using a separate .env file, ensure it is located in the same directory as your compose file and that the variable names match the ones referenced in the compose definition.
Implementing Health Checks for Service Readiness
A subtle but devastating issue arises when WordPress starts before the database is actually ready to accept connections. While the database container may be running, the underlying MySQL process might still be initializing, creating system databases, or applying recovery logs. During this window, any connection attempt will fail. Relying solely on thedepends_on directive in older Docker Compose versions is insufficient because it only waits for the container to start, not for the application inside to become healthy.
To fix this, you must implement health checks. In your docker-compose.yml, define a health check for the database service. This involves specifying a command that queries the database to confirm it is responsive. For example, you can use mysqladmin ping -h localhost or a similar diagnostic command depending on your database image. Set appropriate intervals, timeouts, and retries to allow sufficient time for initialization.
Once the database has a health check defined, you must configure the WordPress service to depend on that health status rather than just the container state. Use the syntax depends_on: db: condition: service_healthy. This ensures that Docker Compose will pause the startup of the WordPress container until the database reports that it is healthy. This approach eliminates race conditions where WordPress crashes repeatedly trying to connect to a sleeping database. If you are migrating from an older setup, removing any legacy depends_on entries without health conditions is a necessary step toward stability.
For more details on managing service dependencies and networking, you might find Binding Docker Compose Services with Provided DNS Services helpful for understanding how services discover each other on the internal network.
Checking Network Connectivity and DNS Resolution
Docker Compose automatically creates a default bridge network for all services defined in the same compose file. Each service can reach others by using the service name as the hostname. Therefore,WORDPRESS_DB_HOST should almost always be set to the exact name of the database service block in your YAML file, such as db or mysql. It should never be set to localhost or 127.0.0.1 from within the WordPress container, as those refer to the container's own loopback interface, not the host machine or other containers.
If you have customized networks in your compose file, ensure both the WordPress and database services are attached to the same network. If they are on different networks, they cannot resolve each other's hostnames unless explicit network aliases are configured. You can test connectivity by executing a temporary shell in the WordPress container using docker compose exec wordpress sh and then attempting to ping the database hostname using ping db. If the ping fails, there is a network segmentation issue. If the ping succeeds but the connection still fails, the problem is likely at the application level (credentials or permissions).
Additionally, check if your database allows remote connections. Some database images restrict access to specific IP ranges or require explicit user privileges for external hosts. Ensure that the database user specified in the WordPress environment has the GRANT privilege to connect from the '%' host or specifically from the Docker network subnet.
Reviewing Logs for Specific Error Messages
When general troubleshooting steps fail, examining the logs provides precise clues about why the connection is failing. Rundocker compose logs wordpress to view the output of the web server. Look for PHP errors related to mysqli_connect or PDO. These messages often specify whether the error was due to authentication failure (Access denied) or connection refusal (Connection refused). An authentication error points back to incorrect passwords or usernames. A connection refusal suggests the database is down, unreachable, or blocking the request.
Conversely, checking the database logs with docker compose logs db can reveal if the database itself encountered issues during startup. Errors regarding disk space, corrupted tables, or failed permission grants here indicate that the database needs repair or reconfiguration before WordPress can interact with it. If the database logs show no activity while WordPress is trying to connect, it confirms that the traffic is not reaching the database container, pointing to a networking or firewall issue within the Docker environment.
For broader context on resolving MySQL connection issues in Docker environments, reviewing MySQL Server Won't Connect to Docker Container on Ubuntu 22.04 may provide additional insights into host-level permissions that could interfere with container communication.
Frequently Asked Questions
Why does my WordPress site show a white screen instead of a database error?
A white screen often indicates that PHP errors are suppressed in the production configuration. To see the actual database error, enable debugging by setting WP_DEBUG to true in your wp-config.php file. This forces WordPress to display the fatal error message, revealing whether the issue is a missing table, bad credentials, or a timeout.
Can I use localhost as the database host in Docker Compose?
No, using localhost inside a WordPress container refers to the container itself, not the host machine or another container. You must use the service name defined in your docker-compose.yml file (e.g., db) as the hostname. Docker's internal DNS resolves service names to the correct internal IP addresses automatically.
What happens if I change the database password after installation?
If you change the database password in the container environment, you must update the corresponding DB_PASSWORD in your wp-config.php file or the environment variables in your compose file. Failure to sync these changes will result in immediate authentication failures. You may need to restart the WordPress container for the new environment variables to take effect.
How do I clear the cache if the database connection error persists after fixing credentials?
Database connection errors are rarely caused by caching issues, so clearing object caches or browser caches usually does not resolve them. However, if you suspect transient data corruption, you can delete the contents of the /tmp directory inside the WordPress container or reset the transients table in the database directly. Focus first on verifying the connection string and health checks.
Is it safe to run WordPress and MySQL in the same container?
While technically possible, it is highly discouraged for production environments. Running both in one container violates the principle of separation of concerns and makes scaling difficult. If the database becomes resource-intensive, it will impact the web server performance within the same process space. Using separate containers allows you to scale and manage each service independently.