iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
The reliable way to add phpMyAdmin to a WordPress Docker Compose stack is to define a third service beside wordpress and db. Set PMA_HOST to the database service name, publish phpMyAdmin’s container port 80 on an available host port such as 8080, and start the project with docker compose up -d. On a local machine, open http://localhost:8080.
Inside Compose, db is a network hostname, not merely a label. Using that name lets phpMyAdmin reach MySQL over the project network; using localhost would point back to the phpMyAdmin container. The arrangement follows phpMyAdmin’s container setup guidance and Docker’s service-name networking model (phpMyAdmin setup documentation; Docker database guide).
Free tools Windows power users keep installed
One-click scans. No signup required.
What you are adding
A Compose project normally contains a WordPress application container and a database container. phpMyAdmin is a web client that runs as a separate container. It does not replace MySQL and it does not store WordPress content; it connects to the database over Docker’s internal network and gives you a browser interface for inspecting tables, running SQL, importing data, and managing users.
Compose creates a shared network for services in the same project. Each service can resolve the others by its service name. If the database service is named db, phpMyAdmin should use PMA_HOST: db. The database remains on its own persistent volume, while phpMyAdmin can be replaced without deleting database data.
#1 Best Overall
Use this Compose file
Create a directory for the project and save the following as compose.yaml (or docker-compose.yml):
services:
db:
image: mysql:8.0
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
volumes:
- db:/var/lib/mysql
wordpress:
image: wordpress
restart: always
ports:
- "8081:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
volumes:
- wordpress:/var/www/html
phpmyadmin:
image: phpmyadmin:latest
restart: always
depends_on:
- db
ports:
- "8080:80"
environment:
PMA_HOST: db
volumes:
db:
wordpress:
This uses the official WordPress image’s database variables and named-volume pattern (WordPress image documentation) and the phpMyAdmin Docker image’s PMA_HOST configuration (phpMyAdmin Docker project). The phpMyAdmin server listens on container port 80; the left side of 8080:80 is the port exposed on your computer.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
What each service does
| Service | Role | Important settings | Host access |
|---|---|---|---|
db |
MySQL 8.0 database | MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD, and a data volume |
Not published to the host in this example |
wordpress |
WordPress web application | WORDPRESS_DB_HOST: db and matching database credentials |
http://localhost:8081 |
phpmyadmin |
Browser-based database administration | PMA_HOST: db and depends_on |
http://localhost:8080 |
Set up and start the stack
1. Check prerequisites
- Install Docker Desktop or a Docker Engine installation that provides the
docker composecommand. - Make sure ports 8080 and 8081 are free, or choose different host-side ports.
- Use a directory where you can keep the Compose file and protect any credential files.
2. Save and review the configuration
Replace the example database name, username, and password before using the file for anything beyond a throwaway local test. The same values must appear in both places: the MYSQL_* settings that initialize MySQL and the matching WORDPRESS_DB_* settings used by WordPress. Keep the service name and the host value aligned: if you rename db to mysql, change both WORDPRESS_DB_HOST and PMA_HOST to mysql.
3. Start all containers
- Open a terminal in the directory containing
compose.yaml. - Run
docker compose up -d. - Wait for MySQL to initialize before trying to log in. The first startup can take longer than subsequent starts because the database volume is created and initialized.
- Check the running services with
docker compose ps.
When initialization completes, Docker’s official WordPress instructions use the same pattern of starting Compose and visiting http://localhost:8080 or the host’s address as appropriate (official WordPress image documentation). In this file, WordPress itself is on port 8081 and phpMyAdmin is on port 8080.
4. Sign in to phpMyAdmin
- Open
http://localhost:8080in a browser. - Enter the database username from
MYSQL_USER, such asexampleuser. - Enter the corresponding
MYSQL_PASSWORD, such asexamplepass. - Use the database host
dbif the login form asks for a server. With a fixedPMA_HOST, the image normally supplies that host automatically.
The example sets MYSQL_RANDOM_ROOT_PASSWORD: '1', so it intentionally does not give you a known root password. Use the configured application user for routine work. If you need administrative operations, create or rotate an administrative account deliberately rather than guessing a root password.
Why PMA_HOST must be the service name
PMA_HOST tells phpMyAdmin which MySQL server to contact. Docker’s internal DNS resolves Compose service names on the shared project network, which is why db works in the example. The value localhost has a different meaning inside a container: it refers to the phpMyAdmin container itself, where MySQL is not running. The phpMyAdmin documentation describes specifying a MySQL host with PMA_HOST (phpMyAdmin Docker documentation).
Both containers must belong to the same Compose project or an explicitly shared Docker network. Starting phpMyAdmin in an unrelated project while leaving MySQL elsewhere means the name db may not resolve and the connection will fail. If your database service has another name, use that exact name, including capitalization and punctuation as written in the Compose file.
Ports: which address to open
The mapping 8080:80 means host port 8080 forwards to port 80 inside the phpMyAdmin container. You browse to the host-side port, not the container port. A mapping such as 8090:80 would therefore be opened at http://localhost:8090. The database has no published port in the example because WordPress and phpMyAdmin reach it through the internal network.
Rank #3
| Need | Compose change | Address |
|---|---|---|
| Default local setup | 8080:80 under phpmyadmin.ports |
http://localhost:8080 |
| Another application already uses 8080 | Change the left side, for example 8090:80 |
http://localhost:8090 |
| WordPress site in the example | 8081:80 under wordpress.ports |
http://localhost:8081 |
Publishing a port makes the service reachable through the host interface. If the machine is reachable from the internet, do not treat the default mapping as a security boundary: use HTTPS, add an authentication layer, and restrict source IPs where possible.
Keep database and WordPress data persistent
The named volume db:/var/lib/mysql stores MySQL’s data files outside the replaceable database container. The wordpress:/var/www/html volume stores WordPress core files, themes, plugins, and uploads. Recreating a container does not remove these named volumes unless you explicitly remove them. The WordPress sample documentation describes this volume approach for preserving database state and WordPress files (Docker WordPress sample).
Do not run docker compose down -v casually: the -v option removes the Compose-managed volumes and can destroy the database and WordPress files stored there. Back up the database before destructive maintenance, and treat the volume as the authoritative state rather than the container itself.
Protect credentials and configuration
The readable example is useful for learning but places a password in the Compose file. For a real project, move values into a local .env file that is excluded from version control and has permissions appropriate for your operating system. Compose can substitute variables into the file, for example:
Rank #4
MYSQL_DATABASE=${MYSQL_DATABASE}
MYSQL_USER=${MYSQL_USER}
MYSQL_PASSWORD=${MYSQL_PASSWORD}
Use a secret-management mechanism when the deployment supports it. The WordPress image accepts _FILE variants of its database variables, and the phpMyAdmin Docker image documents environment-variable and secret-file configuration (WordPress image documentation; phpMyAdmin Docker repository). Docker secrets are documented for Swarm deployments (Docker secrets documentation).
Do not commit .env files containing live passwords. Rotate credentials if they have already been exposed, and update every service that uses the account.
Local-only use versus an internet-facing server
Local development
A host mapping such as 8080:80 is convenient for a developer working on the same machine. Stop the stack when it is not needed, keep the Compose directory private, and avoid exposing the Docker host to untrusted networks.
Remote or public deployment
phpMyAdmin is an administrative interface and should not be left openly reachable without controls. Put it behind HTTPS and an authentication layer, limit access by source IP where feasible, and monitor logs. Use a fixed PMA_HOST for the known database service. Avoid PMA_ARBITRARY=1 unless users genuinely need to choose arbitrary database hosts; that setting enables arbitrary-server entry on the login form (phpMyAdmin setup documentation; phpMyAdmin configuration reference).
Best Value
Useful configuration choices
| Choice | Recommended when | Trade-off |
|---|---|---|
Fixed PMA_HOST |
phpMyAdmin should manage the one database in this Compose project | Simpler and less exposed; the login form does not accept arbitrary servers |
PMA_ARBITRARY=1 |
Administrators must select different database hosts | Broader connection capability and a larger attack surface; secure it carefully |
| Named volumes | You want Docker-managed persistence across container replacement | Files are less convenient to edit directly from the host |
| Bind mounts | You specifically need host-side access to files and understand the permission implications | Host paths and permissions become part of the deployment |
| Environment variables in a protected local file | Small local or development projects | Simple, but secrets remain file-based and must be kept out of source control |
| Docker secrets | A deployment platform supports secret files, such as a Swarm deployment | More setup, but credentials are not embedded directly in the Compose text |
Troubleshoot connection and startup failures
“Cannot connect to MySQL server”
- Confirm that
PMA_HOSTexactly matches the database service name. In the example it isdb, notlocalhostand not the container ID. - Confirm both services were started from the same Compose project and are on the same network.
- Check that the database container is running with
docker compose ps. - Read both logs with
docker compose logs db phpmyadmin. Look for initialization errors, authentication failures, or a database that has not finished starting.
“Access denied” after changing a password
MySQL initialization variables are applied when the data directory is first created. If the db volume already contains an initialized database, changing MYSQL_USER or MYSQL_PASSWORD in Compose does not rewrite the existing account. Update the user inside MySQL using a valid administrative account, or recreate the data only when it is safe and you have a verified backup.
WordPress works but phpMyAdmin does not
Compare the credentials character for character. WordPress may be using values from an older configuration or an existing volume, while the visible Compose file shows new values. Inspect the effective configuration and logs, then use the credentials that actually exist in the initialized database.
The browser cannot open port 8080
- Check
docker compose psfor a published port and a running phpMyAdmin container. - Look for a host application already listening on 8080 and change the left side of the mapping if necessary.
- Use the exact host port you selected, such as
http://localhost:8090after changing the mapping to8090:80. - On a remote machine, replace
localhostwith the server’s address and ensure the host firewall and reverse proxy policy permit the connection.
Updating or removing phpMyAdmin
To recreate only the administration interface, run docker compose pull phpmyadmin followed by docker compose up -d phpmyadmin. The MySQL and WordPress volumes are separate, so replacing phpMyAdmin does not inherently delete their data. Review image tags and test updates in a non-production environment before changing a live stack.
To stop the project without deleting data, use docker compose down. Start it again with docker compose up -d. Remove volumes only as an intentional data-destruction operation after exporting the database and confirming that the backup can be restored.
Quick Recap
Final verification checklist
db,wordpress, andphpmyadminappear as running services.PMA_HOSTequals the database service name.- WordPress and phpMyAdmin use credentials that exist in the initialized database.
- The phpMyAdmin host port is free and matches the URL you open.
- The database and WordPress directories are mounted on persistent volumes.
- Passwords are kept out of committed Compose files, and public deployments have HTTPS and access controls.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

