💡 Quick Stats
- Series: Docker
- Difficulty: Beginner / Intermediate
- Read Time: 5 min
🚀 The Setup
I was building a .NET 8 Web API with PostgreSQL using Docker Compose.
Everything looked fine:
- Containers were running
- Migrations were applied
- API was responding
- Database was created
But PostgreSQL logs were spamming this every 5 seconds:
FATAL: database "train_user" does not exist
The strange part?
The API was working perfectly.
So why was PostgreSQL complaining?
🧱 My Docker Setup
Here’s the relevant docker-compose.yml:
services:
postgres:
image: postgres:16
container_name: train-postgres
environment:
POSTGRES_DB: train_db
POSTGRES_USER: train_user
POSTGRES_PASSWORD: train_pass
ports:
- "5433:5432"
volumes:
- train_pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U train_user"]
interval: 5s
timeout: 5s
retries: 5
api:
build: .
container_name: train-api
ports:
- "8080:8080"
depends_on:
postgres:
condition: service_healthy
environment:
ConnectionStrings__DefaultConnection: "Host=postgres;Port=5432;Database=train_db;Username=train_user;Password=train_pass"
volumes:
train_pgdata:
Looks correct at first glance, right?
🔎 The Clue
The error appeared exactly every 5 seconds.
That matched this line:
interval: 5s
That meant something inside the healthcheck was failing.
🧠 Understanding PostgreSQL Default Behavior
The healthcheck command was:
pg_isready -U train_user
Here’s the important PostgreSQL rule:
If you don’t specify a database, PostgreSQL assumes:
Database name = Username
So this command was actually trying to connect to:
Database: train_user
But my actual database (created using POSTGRES_DB) was:
train_db
That mismatch caused:
FATAL: database "train_user" does not exist
Every 5 seconds.
✅ The Fix
Simply specify the correct database in the healthcheck:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U train_user -d train_db"]
interval: 5s
timeout: 5s
retries: 5
Restart containers:
docker compose down
docker compose up --build
And the log spam disappeared instantly.
🎯 Key Lessons
1️⃣ Container Name ≠ Database Name
| Type | Example |
|---|---|
| Container name | train-postgres |
| Service name (Docker DNS) | postgres |
| Database name | train_db |
They are three completely different things.
2️⃣ PostgreSQL Defaults Can Trick You
If you connect without -d, PostgreSQL uses:
Database = Username
Always specify the database explicitly.
3️⃣ Healthchecks Can Mislead You
A failing healthcheck can:
- Spam logs
- Confuse debugging
- Make you suspect the wrong issue
- Hide the real root cause
Timing patterns in logs are powerful debugging clues.
🏁 Final State
After the fix:
- PostgreSQL container → Healthy
- .NET API → Running
- Database → Correct
- Logs → Clean
- No more FATAL errors
💡 Bonus Improvement
You can make the healthcheck dynamic:
test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"]
This avoids hardcoding values.
🔥 Final Thought
This wasn’t a Docker problem.
It was:
- A PostgreSQL default behavior
- Combined with a small configuration oversight
Sometimes debugging is just about understanding how tools behave by default.
If this helped you, feel free to connect or share your experience debugging Docker setups 👋
Top comments (0)