This guide explains how to run the GTFS Planner application in a Docker container while connecting to a PostgreSQL database running on your host machine.
- Docker Desktop installed (Mac/Windows) or Docker Engine (Linux)
- PostgreSQL running locally on port 5432
- Database created:
gtfs_planner_dev - Database user:
postgreswith passwordpostgres(or adjust the configuration)
If you're using the default PostgreSQL configuration, it should already allow local connections.
If you encounter connection issues, configure PostgreSQL to accept connections from Docker:
-
Edit
postgresql.conf:listen_addresses = '*' -
Edit
pg_hba.conf- Add these lines:# Docker network access host all all 172.17.0.0/16 md5 host all all ::1/128 md5 -
Restart PostgreSQL:
# Mac (Homebrew) brew services restart postgresql@16 # Linux (systemd) sudo systemctl restart postgresql
The easiest way to build and run the container:
# Build the Docker image
./scripts/docker-build.sh
# Run the container
./scripts/docker-run.shThe scripts will:
- Build the Docker image (docker-build.sh)
- Check if PostgreSQL is running
- Verify the database exists
- Detect your OS and configure networking appropriately
- Set all required environment variables
- Start the container (docker-run.sh)
For more control, run Docker directly:
# Build the image
docker build -t gtfs-planner .
# Run the container (Mac/Windows)
docker run -it --rm \
-p 4000:4000 \
-e DATABASE_URL="ecto://postgres:postgres@host.docker.internal/gtfs_planner_dev" \
-e SECRET_KEY_BASE="$(mix phx.gen.secret)" \
-e PHX_SERVER=true \
-e PHX_HOST=localhost \
gtfs-planner
# Run the container (Linux)
docker run -it --rm \
-p 4000:4000 \
--add-host=host.docker.internal:host-gateway \
-e DATABASE_URL="ecto://postgres:postgres@host.docker.internal/gtfs_planner_dev" \
-e SECRET_KEY_BASE="$(mix phx.gen.secret)" \
-e PHX_SERVER=true \
-e PHX_HOST=localhost \
gtfs-plannerOnce the container is running, access the application at:
http://localhost:4000
- Mac/Windows: Docker Desktop automatically provides
host.docker.internalwhich resolves to the host machine's IP - Linux: We use
--add-host=host.docker.internal:host-gatewayto create this mapping
This allows the container to connect to localhost services on the host machine.
┌─────────────────────────┐
│ Docker Container │
│ (Phoenix App) │
│ │
│ Connects to: │
│ host.docker.internal │
└───────────┬─────────────┘
│
│ Resolves to host IP
▼
┌─────────────────────────┐
│ Host Machine │
│ │
│ PostgreSQL on │
│ localhost:5432 │
└─────────────────────────┘
Error: connection refused
Solutions:
-
Verify PostgreSQL is running:
pg_isready -h localhost
-
Check PostgreSQL is listening on the correct port:
lsof -i :5432
-
On Linux, ensure
host.docker.internalis mapped:docker run --add-host=host.docker.internal:host-gateway ...
Error: database "gtfs_planner_dev" does not exist
Solution: Create the database first:
mix ecto.create
# or
createdb -U postgres gtfs_planner_devError: password authentication failed for user "postgres"
Solutions:
-
Update the
DATABASE_URLwith correct credentials:-e DATABASE_URL="ecto://your_user:your_password@host.docker.internal/gtfs_planner_dev" -
Verify you can connect locally:
psql -U postgres -h localhost -d gtfs_planner_dev
Error: could not resolve host.docker.internal
Solution: Make sure to add the --add-host flag:
docker run --add-host=host.docker.internal:host-gateway ...Or use the ./scripts/docker-run.sh script which handles this automatically.
You can customize these environment variables:
| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | ecto://postgres:postgres@host.docker.internal/gtfs_planner_dev |
SECRET_KEY_BASE |
Phoenix secret key base | Generated or default |
PHX_SERVER |
Start Phoenix server | true |
PHX_HOST |
Application host | localhost |
PORT |
HTTP port | 4000 |
Important: This configuration is for local development only. For production:
- Use a proper managed PostgreSQL service (RDS, Cloud SQL, etc.)
- Generate a secure
SECRET_KEY_BASE:mix phx.gen.secret - Use environment-specific configuration
- Enable SSL for database connections
- Use proper secrets management
If you prefer a fully containerized setup, see the main docker-compose.yml example in Option 3 from the analysis document.