-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
162 lines (156 loc) · 6.4 KB
/
docker-compose.yml
File metadata and controls
162 lines (156 loc) · 6.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# Local docker stack for the router. Brings up Postgres, applies migrations, and
# starts the server end-to-end. Suitable for `docker compose up` smoke tests.
#
# DEV ONLY — not tuned for production (single-instance Postgres, no resource
# limits, default credentials below). Do not deploy this compose file to any
# environment exposed beyond localhost.
#
# Usage:
# docker compose up --build
#
# Health checks:
# curl http://localhost:8080/health
# curl -H 'Authorization: Bearer rk_invalid' http://localhost:8080/validate # 401
#
# To seed an installation + API key for testing:
# docker compose run --rm seed
services:
postgres:
image: postgres:15-alpine
# DEV ONLY credentials — replace before exposing this stack anywhere.
environment:
POSTGRES_USER: router
POSTGRES_PASSWORD: router
POSTGRES_DB: router
# Host port 5433 to avoid colliding with the Weave backend's local Postgres
# on 5432. The router service inside the compose network still talks on the
# internal :5432, so this only affects manual `psql` from the host.
ports:
- "5433:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U router -d router"]
interval: 1s
timeout: 3s
retries: 30
volumes:
- router_postgres_data:/var/lib/postgresql/data
# Init script runs once on first DB creation. Creates the `router` schema
# so the migrate sidecar can land its `schema_migrations` table there.
- ./db/init:/docker-entrypoint-initdb.d:ro
# Pub/Sub emulator used for cross-replica cache invalidation. In production
# this is GCP Pub/Sub; locally we run Google's emulator so `docker compose up`
# is self-contained (no GCP credentials required). The entrypoint pre-creates
# the invalidation topic; per-replica subscriptions are created by the router
# itself at startup.
pubsub-emulator:
image: gcr.io/google.com/cloudsdktool/google-cloud-cli:emulators
entrypoint: ["/entrypoint.sh"]
ports:
- "8085:8085"
environment:
PUBSUB_PROJECT_ID: router-local
PUBSUB_TOPIC_ROUTER_INVALIDATION: router-installation-invalidate
volumes:
- ./db/pubsub/entrypoint.sh:/entrypoint.sh:ro
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:8085 >/dev/null || exit 1"]
interval: 2s
timeout: 3s
retries: 30
# One-shot migration runner. Exits with status 0 once all pending migrations
# are applied. The `server` service waits on this via service_completed_successfully
# so it never starts against an unmigrated DB.
migrate:
image: migrate/migrate:v4.17.1
depends_on:
postgres:
condition: service_healthy
volumes:
- ./db/migrations:/migrations
# `search_path=router` makes both the migrations themselves and the
# `schema_migrations` bookkeeping table land in the router schema, so
# nothing leaks into public. The migrations create the schema themselves
# (CREATE SCHEMA IF NOT EXISTS router) before any table DDL runs.
command:
- "-path=/migrations"
- "-database=postgres://router:router@postgres:5432/router?sslmode=disable&search_path=router"
- "up"
restart: "no"
server:
build:
context: .
depends_on:
postgres:
condition: service_healthy
migrate:
condition: service_completed_successfully
pubsub-emulator:
condition: service_healthy
# Load API keys from the same .env files `make dev` uses, so
# docker compose up and make dev resolve identically. Compose
# evaluates env_file entries in order; .env.local wins on
# collisions because it's listed second.
#
# NOTE: do not add ANTHROPIC_API_KEY / OPENAI_API_KEY /
# GOOGLE_API_KEY to the `environment:` block below — that
# block overrides env_file values, and any "${VAR:-}" form there
# would silently zero out the env_file value when run in a shell
# without the var exported. Let env_file be authoritative for the
# provider keys; main.go will panic if ANTHROPIC_API_KEY ends up
# unset and loud-warn for any unregistered provider.
env_file:
- path: .env.development
required: false
- path: .env.local
required: false
environment:
DATABASE_URL: postgres://router:router@postgres:5432/router?sslmode=disable
PORT: "8080"
# .env.development sets ROUTER_ONNX_ASSETS_DIR to a repo-relative path
# that's correct for `make dev` outside Docker but wrong inside the
# container, where the Dockerfile populates /opt/router/assets/. The
# `environment:` block overrides env_file values, so we pin the
# in-container path here. Without this override, the Go embedder's
# resolveAssetsDir() picks up the dev-only path, the cluster scorer
# fails to load, and the router silently falls open to the heuristic.
ROUTER_ONNX_ASSETS_DIR: /opt/router/assets
# .env.local may set ROUTER_ONNX_LIBRARY_DIR to a macOS Homebrew path
# that doesn't exist inside the container. The Dockerfile copies
# libonnxruntime.so to /usr/lib which is on the default linker path.
ROUTER_ONNX_LIBRARY_DIR: /usr/lib
# Pub/Sub broadcast for cross-replica cache invalidation. main.go
# panics at startup if any of these is unset (config.MustGet). The
# gcppubsub client honors PUBSUB_EMULATOR_HOST and routes there
# instead of GCP — so no credentials are needed for local dev.
PUBSUB_EMULATOR_HOST: pubsub-emulator:8085
PUBSUB_PROJECT_ID: router-local
PUBSUB_TOPIC_ROUTER_INVALIDATION: router-installation-invalidate
PUBSUB_SUBSCRIPTION_ROUTER_INVALIDATION: router-installation-invalidate
ports:
- "8080:8080"
restart: unless-stopped
# One-shot seed runner. Creates a local-dev installation + API key and
# prints the raw token with paste-ready configuration for Claude Code and
# Cursor. Not started by `docker compose up`; invoke explicitly:
# docker compose run --rm seed
seed:
image: golang:1.25-bookworm
working_dir: /app
volumes:
- .:/app
- go_modules:/go/pkg/mod
depends_on:
postgres:
condition: service_healthy
migrate:
condition: service_completed_successfully
environment:
CGO_ENABLED: "0"
DATABASE_URL: postgres://router:router@postgres:5432/router?sslmode=disable
command: ["go", "run", "./cmd/seed"]
profiles:
- tools
restart: "no"
volumes:
router_postgres_data:
go_modules: