Add phpMyAdmin as a third service beside your WordPress and database services in the same compose.yaml. Set PMA_HOST to the database service name (usually db), publish phpMyAdmin’s container port 80 on a host port such as 8080, then run docker compose up -d. Open http://localhost:8080 locally and sign in with a database account.
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
What this setup adds
phpMyAdmin is a web interface for administering MySQL-compatible databases. It does not replace the database container or WordPress. Instead, it connects to the database over Docker Compose’s internal network, allowing you to inspect tables, run SQL, export data, and manage users from a browser.
As an Amazon Associate I earn from qualifying purchases.
Free tools Windows power users keep installed
One-click scans. No signup required.
A Compose project normally creates one private network for its services. Docker’s internal DNS resolves each service by its service name, so a database service declared as db is reachable from phpMyAdmin at the hostname db. The value localhost would point back to the phpMyAdmin container, not to MySQL. phpMyAdmin documents the PMA_HOST setting and its web server port in the official setup documentation.
The example below uses MySQL 8.0, the official WordPress image, and phpMyAdmin’s current image tag. It publishes WordPress on port 8081 and phpMyAdmin on port 8080; you can change the host-side ports without changing the container ports.
#1 Best Overall
Prerequisites and folder layout
Install Docker Desktop or a Docker Engine installation that includes the Compose v2 command. Create a project directory and place a file named compose.yaml in it. Run all commands from that directory so Compose uses the intended project network and volumes.
- Docker is running and your user can execute
docker compose. - Host ports 8080 and 8081 are free, or you have chosen replacement ports.
- You have enough disk space for the database and WordPress files.
- You understand that the sample passwords are demonstration values and must be replaced before any shared or public deployment.
Use this Compose file
This is a complete three-service stack. The database and WordPress data are stored in named volumes, while phpMyAdmin is stateless and can be recreated whenever needed.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
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:
The WordPress image documents the WORDPRESS_DB_HOST, WORDPRESS_DB_USER, WORDPRESS_DB_PASSWORD, and WORDPRESS_DB_NAME variables and the named-volume pattern in its image documentation. Docker’s database guide explains service-name networking and the same PMA_HOST approach in its database guide.
What each service does
db: Runs MySQL and creates theexampledbdatabase andexampleuseraccount on first initialization.wordpress: Connects todbon the Compose network and serves the WordPress installer or site on host port 8081.phpmyadmin: Serves its login page from container port 80, published as host port 8080, and sends database connections todbbecause ofPMA_HOST: db.depends_on: Expresses the startup relationship. MySQL can still need additional time to initialize, so wait for its logs to show that it is ready before logging in.
Start the stack and open phpMyAdmin
- Save the Compose file as
compose.yaml. - From that directory, pull images and start the services in the background:
docker compose up -d - Check that all containers are running:
docker compose ps - Open http://localhost:8080 in a browser. The phpMyAdmin server listens on container port 80, which is why the published mapping is
8080:80. - For WordPress, open http://localhost:8081 and complete the site setup if this is a new volume.
The official WordPress image gives the same access pattern: start Compose, wait for initialization, and visit the published localhost address. On another machine, replace localhost with the host name or IP address only when you have deliberately exposed the port and secured the service.
Rank #2
Sign in with the database credentials
At the phpMyAdmin login screen, enter:
- Server: leave the preselected server if it is already
db; the fixedPMA_HOSTvalue supplies it. - Username:
exampleuser. - Password:
examplepass.
The account works because it matches MYSQL_USER and MYSQL_PASSWORD in the database service. It also matches the WordPress connection variables, so WordPress and phpMyAdmin use the same database account. The sample sets MYSQL_RANDOM_ROOT_PASSWORD: '1'; MySQL generates a root password rather than setting a known root password in the file. If you need administrative operations, retrieve or reset that root credential using your database-administration procedure instead of assuming the application account has full privileges.
How Docker networking makes PMA_HOST work
Compose gives the services a shared project network and registers service names in internal DNS. In this file, db resolves to the MySQL container’s current network address even if the container is replaced. No host-port mapping is required for phpMyAdmin to reach MySQL; the connection stays inside the Docker network.
Do not set PMA_HOST to localhost or to the host-published port. Inside the phpMyAdmin container, localhost means that same container, and 8080 is the host-side HTTP port, not MySQL’s database port. If you rename the database service to mysql, change both WORDPRESS_DB_HOST and PMA_HOST to mysql. If the services are started from different Compose projects, they normally do not share a network or service-name DNS; put them in one project or explicitly attach both to a shared external network.
Keep database and WordPress data persistent
The db volume mounted at /var/lib/mysql stores the database files. The wordpress volume mounted at /var/www/html stores WordPress core files, themes, plugins, and uploads. Named volumes survive ordinary container replacement, so docker compose up -d after an image update does not create an empty site.
The official WordPress sample documents this persistence model in its Compose example. A command such as docker compose down removes containers but leaves named volumes unless you add the volume-removal option. Treat docker compose down -v as destructive: it removes the declared volumes and therefore the database and WordPress data.
Initialization variables are not migrations
MySQL initialization variables are applied when the data directory is empty. If the db volume already contains an initialized database, changing MYSQL_PASSWORD, MYSQL_USER, or MYSQL_DATABASE in Compose does not rewrite the existing account or database. Change credentials inside MySQL, or remove and recreate the data volume only when you have a verified backup and are intentionally starting over.
Move credentials out of the Compose file
Literal passwords make the example easy to understand but are unsafe in a committed repository. Put values in a local .env file with restrictive filesystem permissions, or use Docker secrets where your deployment supports them. The WordPress image supports the corresponding _FILE variables, and the phpMyAdmin Docker project documents environment-variable and secret-file configuration in its repository documentation.
A simple variable-based arrangement keeps the Compose file shareable:
Rank #4
services:
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
wordpress:
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
WORDPRESS_DB_USER: ${MYSQL_USER}
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
phpmyadmin:
environment:
PMA_HOST: db
Create .env beside compose.yaml, add it to your ignore rules, and verify that backups and CI systems do not publish it. For Swarm deployments, Docker’s secrets documentation explains the secret lifecycle and file mounts.
Local access versus public exposure
For a personal development machine, 8080:80 is convenient. To bind only to the local interface, use a host mapping such as 127.0.0.1:8080:80; this prevents remote machines from reaching the port through the host’s network interfaces. If another local device must connect, use the host address deliberately and configure a firewall.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchDo not expose an unprotected phpMyAdmin login directly to the internet. If remote administration is required:
- Put the service behind HTTPS so credentials and SQL results are encrypted in transit.
- Add an authentication layer at the reverse proxy and restrict access to known source IP ranges or a private VPN.
- Keep the phpMyAdmin image updated and monitor access logs.
- Use a least-privileged database account for routine WordPress work.
- Do not enable arbitrary-server mode unless users genuinely need to select database hosts.
phpMyAdmin’s PMA_ARBITRARY setting enables arbitrary-server entry on the login form. Leaving it unset keeps the connection target fixed by PMA_HOST, which is safer for a single-stack deployment. The security guidance and variable behavior are described in the phpMyAdmin setup documentation.
Best Value
Choose the right variant for your deployment
| Decision | Recommended starting point | Trade-off or required check |
|---|---|---|
| Database image | Keep mysql:8.0 for this example |
If you switch to a MariaDB image, change the database service and test the WordPress and phpMyAdmin combination before migrating production data. |
| Host exposure | Local-only binding for development | Public reachability requires HTTPS, an authentication layer, firewall restrictions, and ongoing updates. |
| Storage | Named volumes for /var/lib/mysql and /var/www/html |
Bind mounts expose host paths and can simplify file inspection, but ownership, permissions, and backup handling become your responsibility. |
| Secrets | .env outside version control for a small local project |
Docker secrets or an equivalent secret manager are preferable where multiple operators or production deployment is involved. |
| Database selection | Fixed PMA_HOST: db |
PMA_ARBITRARY=1 adds a server field and a larger attack surface; use it only for a real multi-host administration requirement. |
Troubleshoot connection and login failures
phpMyAdmin shows a connection error
- Confirm the service name in Compose is exactly
dband thatPMA_HOST: dbhas the same spelling and capitalization. - Check that both services belong to the same Compose project. Run
docker compose psfrom the directory containing the file. - Inspect startup output:
docker compose logs db phpmyadmin - Wait for MySQL initialization to finish, then refresh phpMyAdmin. A container can be running while the database process is still preparing its data directory.
Access is refused on port 8080
Run docker compose ps and verify the phpMyAdmin port publication. If another process owns host port 8080, change only the host side, for example 8082:80, restart with docker compose up -d, and browse to http://localhost:8082. The right side remains 80 because that is the port phpMyAdmin listens on inside its container.
WordPress works but phpMyAdmin login fails
Compare the username, password, and database name in the two services. phpMyAdmin can connect to the server while still rejecting a login when the account password differs from the value shown in Compose. Remember that changing MYSQL_PASSWORD after the first database initialization does not change an existing MySQL account. Correct the account inside MySQL or use a newly initialized volume only after preserving the data.
Recommended Free Tools
The database container repeatedly restarts
Read the database logs first. Common causes include an invalid environment value, insufficient disk space, a damaged or incompatible existing data directory, or a host permission problem with a bind mount. Do not delete the db volume as a first reaction; export or back up recoverable data before destructive actions.
Services were started from separate files
If WordPress and phpMyAdmin cannot resolve db, they may be attached to different project networks because each Compose invocation created its own network. Consolidate the services into one Compose file, or deliberately configure a shared external network and use the correct database service alias.
Safe administration habits
- Take a database backup before structural changes, bulk edits, plugin troubleshooting, or user-table work.
- Use phpMyAdmin’s export tools to create a restorable SQL dump and verify that the file can be read before deleting anything.
- Prefer targeted SQL statements and transactions where supported; avoid editing serialized WordPress option values casually because malformed serialization can break the site.
- Keep phpMyAdmin available only when needed on a server, or stop the service after maintenance with
docker compose stop phpmyadmin. - Document which account is used by WordPress and which account is reserved for administrative operations.
Remove or update phpMyAdmin without touching WordPress
Because phpMyAdmin has no data volume in this example, you can recreate it independently:
docker compose pull phpmyadmin
docker compose up -d phpmyadmin
To stop its web interface while leaving WordPress and MySQL running, use docker compose stop phpmyadmin. To remove only its container, use docker compose rm -s phpmyadmin and start it again later with docker compose up -d phpmyadmin. Do not use volume-removal flags unless you intentionally want to erase the database or WordPress volumes.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →In practice
The reliable pattern is simple: keep all three services in one Compose project, use the database service name as PMA_HOST, publish container port 80 on a host port you control, and align phpMyAdmin credentials with the existing MySQL account. Named volumes preserve the site, while careful secret handling and restricted network exposure keep the administration interface from becoming an unnecessary entry point.
Quick Recap
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.




