Linux & servers
Why can’t my Docker app connect to MySQL using localhost?
Short answer
In a normal Docker bridge network, localhost means the app container itself. If MySQL runs in another Compose service, use that service name and its internal database port.
What changes the answer
- Where MySQL actually runs
- Whether both containers share a network
- Database readiness and account permissions
Localhost changes meaning inside a container
An application that worked directly on your VPS may stop connecting after you put it in Docker. Its database setting still says localhost, but the application now has a separate network environment. It is looking for MySQL inside its own container.
This explanation applies to ordinary bridge networking. Host networking and containers that deliberately share a network namespace behave differently, so check your deployment before changing configuration.
Use the service name between Compose containers
Suppose your Compose file defines services named app and db. When they share the Compose network, the application can use db as the database hostname. For a MySQL server listening on its usual port, the connection would use db:3306.
If the database publishes host port 3307 to container port 3306, another container on the same network still uses the internal port, 3306. The published port is for connections through the host. Using it inside the app is a common source of confusion.
Use the service name rather than copying a container IP address. Container addresses can change when services are recreated.
A correct hostname does not fix every connection error
Check that both services join the same network. Then read the actual error: an unresolved hostname, a refused connection and an authentication failure point to different problems.
MySQL may still be starting when the app first tries to connect. Use database health checks and an appropriate connection retry policy. If authentication fails, check the database name, credentials and account permissions without pasting secrets into public logs.
If MySQL runs on the VPS itself, the Compose service-name example does not apply. You need a reachable host address and database access rules for that network. Do not expose MySQL to the public internet just to make the container connect.