fifteen/docker-compose.yml

154 lines
5.7 KiB
YAML

services:
# ─── PostgreSQL + PostGIS ──────────────────────────────────────────────────
postgres:
image: postgis/postgis:16-3.4
restart: unless-stopped
environment:
POSTGRES_DB: fifteenmin
POSTGRES_USER: app
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./infra/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d fifteenmin"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
# ─── Valkey ───────────────────────────────────────────────────────────────
valkey:
image: valkey/valkey:8-alpine
restart: unless-stopped
command: valkey-server --appendonly yes --requirepass ${VALKEY_PASSWORD}
volumes:
- valkey_data:/data
healthcheck:
test: ["CMD", "valkey-cli", "-a", "${VALKEY_PASSWORD}", "ping"]
interval: 10s
timeout: 5s
retries: 5
# ─── Valhalla road worker (port 8002) ─────────────────────────────────────
# Builds road-only tiles (no transit data) → cycling/walking/driving routing.
# Without GTFS in its volume, valhalla_build_tiles produces clean road tiles
# with no ghost transit edges, so bicycle routing works correctly.
valhalla:
build:
context: .
target: valhalla-worker
restart: unless-stopped
volumes:
- osm_data:/data/osm:ro # PBF files downloaded by the main worker
- valhalla_tiles:/data/valhalla # Road-only config and tiles
environment:
REDIS_HOST: valkey
REDIS_PORT: "6379"
REDIS_PASSWORD: ${VALKEY_PASSWORD}
VALHALLA_QUEUE_NAME: valhalla
OSM_DATA_DIR: /data/osm
VALHALLA_CONFIG: /data/valhalla/valhalla.json
VALHALLA_TILES_DIR: /data/valhalla/valhalla_tiles
NODE_ENV: production
ports:
- "127.0.0.1:8002:8002" # Valhalla HTTP API (road)
depends_on:
valkey:
condition: service_healthy
# ─── Valhalla transit worker (port 8002 internal) ─────────────────────────
# Builds tiles with GTFS transit data → multimodal routing.
# Separate volume from the road worker so transit ghost edges never affect
# the road instance.
valhalla-transit:
build:
context: .
target: valhalla-worker
restart: unless-stopped
volumes:
- osm_data:/data/osm:ro # PBF files downloaded by the main worker
- valhalla_tiles_transit:/data/valhalla # Transit config, tiles and GTFS data
environment:
REDIS_HOST: valkey
REDIS_PORT: "6379"
REDIS_PASSWORD: ${VALKEY_PASSWORD}
VALHALLA_QUEUE_NAME: valhalla-transit
OSM_DATA_DIR: /data/osm
VALHALLA_CONFIG: /data/valhalla/valhalla.json
VALHALLA_TILES_DIR: /data/valhalla/valhalla_tiles
NODE_ENV: production
# Optional: connect-info.net token for NDS-specific GTFS feed
CONNECT_INFO_TOKEN: ${CONNECT_INFO_TOKEN:-}
depends_on:
valkey:
condition: service_healthy
# ─── Protomaps tile server ─────────────────────────────────────────────────
tiles:
image: ghcr.io/protomaps/go-pmtiles:latest
restart: unless-stopped
volumes:
- pmtiles_data:/data
command: serve /data --cors "*"
ports:
- "127.0.0.1:8080:8080"
# ─── Next.js web application ───────────────────────────────────────────────
web:
build:
context: .
target: web
restart: unless-stopped
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@postgres:5432/fifteenmin
REDIS_HOST: valkey
REDIS_PORT: "6379"
REDIS_PASSWORD: ${VALKEY_PASSWORD}
VALHALLA_URL: http://valhalla:8002
VALHALLA_TRANSIT_URL: http://valhalla-transit:8002
ADMIN_PASSWORD_HASH: ${ADMIN_PASSWORD_HASH}
ADMIN_JWT_SECRET: ${ADMIN_JWT_SECRET}
NODE_ENV: production
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
# ─── BullMQ pipeline worker ───────────────────────────────────────────────
worker:
build:
context: .
target: worker
restart: unless-stopped
environment:
DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@postgres:5432/fifteenmin
REDIS_HOST: valkey
REDIS_PORT: "6379"
REDIS_PASSWORD: ${VALKEY_PASSWORD}
OSM_DATA_DIR: /data/osm
LUA_SCRIPT: /app/infra/osm2pgsql.lua
VALHALLA_URL: http://valhalla:8002
VALHALLA_TRANSIT_URL: http://valhalla-transit:8002
NODE_ENV: production
# Optional: enables NDS-specific GTFS source for cities in Niedersachsen
CONNECT_INFO_TOKEN: ${CONNECT_INFO_TOKEN:-}
volumes:
- osm_data:/data/osm # Worker downloads PBF here
depends_on:
postgres:
condition: service_healthy
valkey:
condition: service_healthy
volumes:
postgres_data:
valkey_data:
osm_data: # Shared: worker writes, valhalla containers read
valhalla_tiles: # Road-only tiles (no transit) — cycling works correctly here
valhalla_tiles_transit: # Transit tiles (with GTFS) — multimodal routing
pmtiles_data: