Connecting to Databases in Docker Containers
Build connection strings for databases running in Docker. Covers host-to-container, container-to-container, docker-compose networking, and port mapping.
Detailed Explanation
Docker Database Networking
When running databases in Docker containers, the connection string depends on where the client is running relative to the container.
Scenario 1: Host to Container
Your app runs on the host machine, the database runs in a container with published ports:
# docker-compose.yml
services:
postgres:
image: postgres:16
ports:
- "5432:5432"
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: secret
POSTGRES_DB: mydb
Connection string from the host:
postgresql://myuser:secret@localhost:5432/mydb
The key here is localhost with the published port (the left side of the ports mapping).
Scenario 2: Container to Container (same network)
Both app and database run in Docker on the same network:
services:
app:
build: .
depends_on:
- postgres
postgres:
image: postgres:16
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: secret
POSTGRES_DB: mydb
Connection string from the app container:
postgresql://myuser:secret@postgres:5432/mydb
Use the service name (postgres) as the host. Docker Compose creates a DNS entry for each service. Use the container port (the right side of any ports mapping, or the default if no ports are published).
Scenario 3: Custom Network
docker network create mynet
docker run -d --name mydb --network mynet -e POSTGRES_PASSWORD=secret postgres:16
docker run -d --name myapp --network mynet myapp-image
Connection string from myapp:
postgresql://postgres:secret@mydb:5432/postgres
Common Pitfalls
Using
localhostinside a container — Inside a container,localhostrefers to the container itself, not the host. Use the service name or container name instead.Port confusion — Published ports are for host access. Containers on the same network use the internal port (e.g., 5432 for PostgreSQL, not the mapped port).
Waiting for readiness — Use
depends_onwith health checks to ensure the database is ready before your app tries to connect:
services:
postgres:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U myuser"]
interval: 5s
timeout: 5s
retries: 5
app:
depends_on:
postgres:
condition: service_healthy
Use Case
Setting up a local development environment with Docker Compose, running integration tests against containerized databases, or configuring microservices that communicate with database containers on a shared Docker network.