Set DATABASE_URL in my shell, ran docker compose up, but inside the container:
echo $DATABASE_URL
# (empty)The variable was definitely set in my terminal:
echo $DATABASE_URL
# postgresql://user:pass@localhost:5432/mydbRoot cause:
My docker-compose.yml had:
services:
api:
environment:
- DATABASE_URLThis syntax tells Docker Compose to pass the DATABASE_URL from the host shell. But I was running Compose with sudo in one terminal and had set the variable in a different user's session.
Actually — the real issue:
I was running with sudo docker compose up. When you sudo, the environment variables of the regular user don't carry over.
Fix 1: Use .env file (recommended)
# .env file (in same directory as docker-compose.yml)
DATABASE_URL=postgresql://user:pass@localhost:5432/mydbDocker Compose automatically loads .env from the project directory.
Fix 2: Inline the value in docker-compose.yml
services:
api:
environment:
- DATABASE_URL=postgresql://user:pass@localhost:5432/mydbNot ideal for secrets but works for debugging.
Fix 3: Pass sudo with env
sudo -E docker compose up # -E preserves environment variablesLesson: Docker Compose's env_file and .env handling is more reliable than relying on shell environment, especially when sudo is involved. Always use a .env file for local development.