diff --git a/.env.example b/.env.example index dee152c..bf52801 100644 --- a/.env.example +++ b/.env.example @@ -5,13 +5,13 @@ DATABASE_URL=postgres://wrenn:wrenn@localhost:5432/wrenn?sslmode=disable REDIS_URL=redis://localhost:6379/0 # Control Plane -CP_LISTEN_ADDR=:8000 +CP_LISTEN_ADDR=:8080 # Host Agent AGENT_LISTEN_ADDR=:50051 AGENT_FILES_ROOTDIR=/var/lib/wrenn AGENT_HOST_INTERFACE=eth0 -AGENT_CP_URL=http://localhost:8000 +AGENT_CP_URL=http://localhost:8080 # Lago (billing — external service) LAGO_API_URL=http://localhost:3000 diff --git a/Makefile b/Makefile index 4a2e0b6..80fbd3a 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ dev: dev-infra migrate-up dev-cp dev-infra: docker compose -f deploy/docker-compose.dev.yml up -d @echo "Waiting for PostgreSQL..." - @until pg_isready -h localhost -p 5432 -q; do sleep 0.5; done + @until docker compose -f deploy/docker-compose.dev.yml exec -T postgres pg_isready -q 2>/dev/null; do sleep 0.5; done @echo "Dev infrastructure ready." dev-down: @@ -53,7 +53,7 @@ dev-agent: sudo go run ./cmd/host-agent dev-frontend: - cd frontend && pnpm dev --port 5173 + cd frontend && pnpm dev --port 5173 --host 0.0.0.0 dev-envd: cd $(ENVD_DIR) && go run . --debug --listen-tcp :3002 diff --git a/deploy/Caddyfile.dev b/deploy/Caddyfile.dev new file mode 100644 index 0000000..789f8df --- /dev/null +++ b/deploy/Caddyfile.dev @@ -0,0 +1,41 @@ +# Sandbox port forwarding: {port}-{sandbox_id}.localhost +# Matches subdomains like 49999-sb-abcd1234.localhost and proxies them +# to the control plane, which inspects the Host header and routes to +# the correct host agent. +# +# NOTE: Wildcard *.localhost DNS resolution requires local setup. +# Option 1: Add entries to /etc/hosts for each sandbox +# Option 2: Use dnsmasq: address=/.localhost/127.0.0.1 +# Option 3: Use systemd-resolved (Ubuntu default — *.localhost resolves to 127.0.0.1) +http://*.localhost { + reverse_proxy host.docker.internal:8080 +} + +# Main entry point: API + frontend +http://localhost { + # API routes — strip /api prefix and proxy to the control plane. + # The frontend calls /api/v1/... which becomes /v1/... at the CP. + handle_path /api/* { + reverse_proxy host.docker.internal:8080 + } + + # Backend routes served directly (SDK clients, OAuth initiation) + handle /v1/* { + reverse_proxy host.docker.internal:8080 + } + handle /openapi.yaml { + reverse_proxy host.docker.internal:8080 + } + handle /docs { + reverse_proxy host.docker.internal:8080 + } + handle /auth/oauth/* { + reverse_proxy host.docker.internal:8080 + } + + # Everything else — proxy to the frontend dev server + # This includes: /login, /dashboard/*, /admin/*, /auth/github/callback + handle { + reverse_proxy host.docker.internal:5173 + } +} diff --git a/deploy/docker-compose.dev.yml b/deploy/docker-compose.dev.yml index ebcd308..28f401f 100644 --- a/deploy/docker-compose.dev.yml +++ b/deploy/docker-compose.dev.yml @@ -15,19 +15,14 @@ services: ports: - "6379:6379" - prometheus: - image: prom/prometheus:latest + caddy: + image: caddy:2-alpine ports: - - "9090:9090" + - "8000:80" volumes: - - ./deploy/prometheus.yml:/etc/prometheus/prometheus.yml - - grafana: - image: grafana/grafana:latest - ports: - - "3001:3000" - environment: - GF_SECURITY_ADMIN_PASSWORD: admin + - ./Caddyfile.dev:/etc/caddy/Caddyfile:ro + extra_hosts: + - "host.docker.internal:host-gateway" volumes: pgdata: diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 89afaba..350070b 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -7,7 +7,7 @@ export default defineConfig({ server: { proxy: { '/api': { - target: 'http://localhost:8000', + target: 'http://localhost:8080', rewrite: (path) => path.replace(/^\/api/, '') } }