diff --git a/tools/dev-deploy/.env.example b/tools/dev-deploy/.env.example new file mode 100644 index 0000000..12c3a19 --- /dev/null +++ b/tools/dev-deploy/.env.example @@ -0,0 +1,21 @@ +# Defaults for the long-lived dev stack. Copy to `.env` and edit +# per-environment overrides. Everything in this file is non-secret; +# real credentials would go through Gitea Actions secrets and never +# this file. +# +# The compose `${VAR:-default}` expansions fall back to the values +# baked into `docker-compose.yml`, so this file documents the knobs +# rather than driving them. + +# Auto-provisioned sandbox bootstrap. Empty disables the bootstrap. +BACKEND_DEV_SANDBOX_EMAIL=dev@galaxy.lan +BACKEND_DEV_SANDBOX_ENGINE_IMAGE=galaxy-engine:dev +BACKEND_DEV_SANDBOX_ENGINE_VERSION=0.1.0 +BACKEND_DEV_SANDBOX_PLAYER_COUNT=20 + +# `123456` short-circuits the email-code path for the dev account. +# Leave empty in environments where real Mailpit codes must be used. +BACKEND_AUTH_DEV_FIXED_CODE=123456 + +# Name of the external Docker bridge the host Caddy is attached to. +GALAXY_EDGE_NETWORK=edge diff --git a/tools/dev-deploy/Caddyfile.dev b/tools/dev-deploy/Caddyfile.dev new file mode 100644 index 0000000..64758b7 --- /dev/null +++ b/tools/dev-deploy/Caddyfile.dev @@ -0,0 +1,25 @@ +# Application-routing Caddy for the long-lived dev environment. +# Listens only on the `edge` Docker network; TLS termination and the +# real `:80`/`:443` listeners belong to the host Caddy in front of us. +# +# `/srv/galaxy-ui` is mounted from the `galaxy-dev-ui-dist` named volume, +# refreshed on every dev-deploy run. + +{ + auto_https off +} + +:80 { + @frontend host www.galaxy.lan + handle @frontend { + root * /srv/galaxy-ui + try_files {path} /index.html + file_server + encode zstd gzip + } + + @api host api.galaxy.lan + handle @api { + reverse_proxy galaxy-api:8080 + } +} diff --git a/tools/dev-deploy/Caddyfile.prod b/tools/dev-deploy/Caddyfile.prod new file mode 100644 index 0000000..5784c28 --- /dev/null +++ b/tools/dev-deploy/Caddyfile.prod @@ -0,0 +1,15 @@ +# Production placeholder. Mirrors `Caddyfile.dev` but uses real +# hostnames and lets Caddy auto-provision TLS certificates. Not used +# until prod-deploy plumbing exists; kept under version control so the +# dev/prod surface stays symmetric. + +www.galaxy.com { + root * /srv/galaxy-ui + try_files {path} /index.html + file_server + encode zstd gzip +} + +api.galaxy.com { + reverse_proxy galaxy-api:8080 +} diff --git a/tools/dev-deploy/Makefile b/tools/dev-deploy/Makefile new file mode 100644 index 0000000..403054b --- /dev/null +++ b/tools/dev-deploy/Makefile @@ -0,0 +1,105 @@ +.PHONY: help up down rebuild logs status clean-data health psql build-engine seed-ui + +.DEFAULT_GOAL := help + +REPO_ROOT := $(realpath $(CURDIR)/../..) +ENGINE_IMAGE := galaxy-engine:dev +ENGINE_LABEL := org.opencontainers.image.title=galaxy-game-engine +# Game-state root lives under the invoking user's home by default so +# `make up` works without sudo. Override `GALAXY_DEV_GAME_STATE_DIR` +# in the environment or `.env` to relocate (e.g. /var/lib/galaxy-dev/ +# game-state in a production-shaped host). The value flows through to +# both the compose bind-mount and the backend's +# `BACKEND_GAME_STATE_ROOT`. +export GALAXY_DEV_GAME_STATE_DIR ?= $(HOME)/.galaxy-dev/game-state + +COMPOSE := docker compose + +help: + @echo "Long-lived Galaxy dev environment (https://*.galaxy.lan):" + @echo " make up Build images, ensure engine image, bring stack up" + @echo " make rebuild Force rebuild of backend / gateway images and bring up" + @echo " make build-engine Build $(ENGINE_IMAGE) from game/Dockerfile (no-op if present)" + @echo " make seed-ui Build ui/frontend and load into galaxy-dev-ui-dist volume" + @echo " make down Stop containers, keep named volumes" + @echo " make logs Tail all logs" + @echo " make status docker compose ps" + @echo " make health Probe the stack through the host Caddy" + @echo " make psql Open a psql shell as galaxy@galaxy_backend" + @echo " make clean-data Stop everything and wipe named volumes + game-state" + @echo "" + @echo "Requires:" + @echo " - external Docker network '$${GALAXY_EDGE_NETWORK:-edge}'" + @echo " (docker network create edge)" + @echo " - host Caddy proxying *.galaxy.lan into that network" + @echo " - game-state dir: $(GALAXY_DEV_GAME_STATE_DIR) (auto-created)" + +up: build-engine + mkdir -p "$(GALAXY_DEV_GAME_STATE_DIR)" + $(COMPOSE) up -d --wait + +rebuild: build-engine + $(COMPOSE) build --no-cache galaxy-backend galaxy-api + mkdir -p "$(GALAXY_DEV_GAME_STATE_DIR)" + $(COMPOSE) up -d --wait + +build-engine: + @if docker image inspect $(ENGINE_IMAGE) >/dev/null 2>&1; then \ + echo "$(ENGINE_IMAGE) already built; skipping (use 'docker rmi $(ENGINE_IMAGE)' to force a rebuild)."; \ + else \ + echo "building $(ENGINE_IMAGE)…"; \ + docker build -t $(ENGINE_IMAGE) -f $(REPO_ROOT)/game/Dockerfile $(REPO_ROOT); \ + fi + +# Build the UI frontend and load the resulting build/ directory into +# the named volume Caddy serves from. Used by the dev-deploy workflow +# and by anyone bringing the stack up by hand. +seed-ui: + @if [ ! -d $(REPO_ROOT)/ui/frontend/node_modules ]; then \ + echo "installing UI dependencies…"; \ + (cd $(REPO_ROOT)/ui && pnpm install --frozen-lockfile); \ + fi + @echo "building UI (vite build)…" + (cd $(REPO_ROOT)/ui/frontend && \ + VITE_GATEWAY_BASE_URL=https://api.galaxy.lan \ + VITE_GATEWAY_RESPONSE_PUBLIC_KEY=$$(cat $(REPO_ROOT)/ui/frontend/.env.development \ + | sed -n 's/^VITE_GATEWAY_RESPONSE_PUBLIC_KEY=//p') \ + pnpm build) + @echo "loading build/ into galaxy-dev-ui-dist volume…" + docker volume create galaxy-dev-ui-dist >/dev/null + docker run --rm \ + -v galaxy-dev-ui-dist:/dst \ + -v $(REPO_ROOT)/ui/frontend/build:/src:ro \ + alpine sh -c 'rm -rf /dst/* /dst/.??* 2>/dev/null; cp -a /src/. /dst/' + +down: + $(COMPOSE) down + +logs: + $(COMPOSE) logs -f --tail=100 + +status: + $(COMPOSE) ps + +health: + @echo "Frontend (https://www.galaxy.lan):" + @curl -sS -o /dev/null -w " HTTP %{http_code}\n" https://www.galaxy.lan/ || echo " unreachable" + @echo "API healthz (https://api.galaxy.lan/healthz):" + @curl -sS -o /dev/null -w " HTTP %{http_code}\n" https://api.galaxy.lan/healthz || echo " unreachable" + +psql: + $(COMPOSE) exec galaxy-postgres psql -U galaxy -d galaxy_backend + +clean-data: + @echo "Stopping containers and engines, then wiping volumes + game-state…" + @ids=$$(docker ps -aq --filter label=$(ENGINE_LABEL)); \ + if [ -n "$$ids" ]; then \ + echo "stopping engine containers…"; \ + docker rm -f $$ids >/dev/null; \ + fi + $(COMPOSE) down -v + @if [ -d "$(GALAXY_DEV_GAME_STATE_DIR)" ]; then \ + echo "wiping $(GALAXY_DEV_GAME_STATE_DIR)…"; \ + docker run --rm -v "$(GALAXY_DEV_GAME_STATE_DIR):/state" alpine sh -c 'rm -rf /state/*' 2>/dev/null \ + || rm -rf "$(GALAXY_DEV_GAME_STATE_DIR)"/* 2>/dev/null || true; \ + fi diff --git a/tools/dev-deploy/README.md b/tools/dev-deploy/README.md new file mode 100644 index 0000000..0728d1b --- /dev/null +++ b/tools/dev-deploy/README.md @@ -0,0 +1,188 @@ +# `tools/dev-deploy/` — long-lived Galaxy dev environment + +A docker-compose stack that runs the Galaxy backend, gateway, supporting +services, and a small Caddy in front of them, reachable through the host +Caddy at `https://www.galaxy.lan` and `https://api.galaxy.lan`. Used by +the `dev-deploy.yaml` Gitea Actions workflow as the canonical dev target +on every merge into the `development` branch, and runnable by hand +through this Makefile for local debugging of the deploy plumbing +itself. + +This stack is **not** the developer's primary playground for UI work — +that role still belongs to [`tools/local-dev/`](../local-dev/README.md), +which is faster (Vite HMR, host-side dev server) and isolated to one +developer. The two stacks coexist on the same host because every name +is distinct: + +| | `tools/local-dev/` | `tools/dev-deploy/` | +|------------------|------------------------------|-----------------------------| +| Compose project | `local-dev` | `galaxy-dev` | +| Container prefix | `galaxy-local-dev-*` | `galaxy-dev-*` | +| Network | `galaxy-local-dev-net` | `galaxy-dev-internal`, `edge` | +| Volumes | `galaxy-local-dev-*` | `galaxy-dev-*` | +| Host ports | 5433/6380/8025/8080/9090 | none (only `edge` network) | +| Game state | `/tmp/galaxy-game-state` | `/var/lib/galaxy-dev/game-state` | +| Engine image | `galaxy-engine:local-dev` | `galaxy-engine:dev` | + +## Prerequisites + +The host must already provide: + +- Docker daemon reachable as the user running `make` (member of the + `docker` group, no sudo). +- An external bridge network named `edge` (or whatever + `GALAXY_EDGE_NETWORK` overrides to): + + ```sh + docker network create edge + ``` + +- A host Caddy listening on `:80`/`:443`, attached to the `edge` + network, and proxying `www.galaxy.lan` and `api.galaxy.lan` to + `galaxy-caddy:80`. Example fragment for the host Caddyfile: + + ```caddy + www.galaxy.lan, api.galaxy.lan { + tls internal + reverse_proxy galaxy-caddy:80 + } + ``` + +- Game-state directory writable by the user running `make`. Default + is `${HOME}/.galaxy-dev/game-state`; `make up` creates it on demand. + Override by exporting `GALAXY_DEV_GAME_STATE_DIR` (e.g. to + `/var/lib/galaxy-dev/game-state` once the host is provisioned for + it). + +## Bring it up + +```sh +make -C tools/dev-deploy up +``` + +`up` (re)builds the local-dev backend and gateway images, makes sure the +engine image `galaxy-engine:dev` exists, and waits for healthchecks. It +does **not** seed the UI volume — that is normally done by CI. The first +time you run by hand: + +```sh +make -C tools/dev-deploy seed-ui +make -C tools/dev-deploy up +make -C tools/dev-deploy health +``` + +`seed-ui` runs `pnpm build` in `ui/frontend/`, then copies the resulting +`build/` tree into the `galaxy-dev-ui-dist` volume. Subsequent CI deploys +overwrite this volume automatically. + +## Daily flow + +```sh +make -C tools/dev-deploy rebuild # rebuild backend/gateway images + up +make -C tools/dev-deploy logs # tail compose logs +make -C tools/dev-deploy health # probe https://*.galaxy.lan +make -C tools/dev-deploy down # stop, keep state +``` + +State persists in named volumes between `up`/`down` cycles. The +`development` branch keeps the dev environment continuously usable — +games created last week survive into this week unless somebody +calls `make clean-data`. + +## Logging in + +The same dev-mode email-code override as `tools/local-dev/` applies: + +1. Enter `dev@galaxy.lan` (or whatever `BACKEND_DEV_SANDBOX_EMAIL` + resolves to) in the login form. +2. Submit `123456` as the code if `BACKEND_AUTH_DEV_FIXED_CODE` is + non-empty. Otherwise open Mailpit at + `http://galaxy-mailpit:8025/` from inside the network or proxy it + through the host Caddy when needed. + +The fixed-code override is rejected by production env loaders, so it +cannot leak into the prod environment. + +## Networking + +``` +Browser + │ https://www.galaxy.lan, https://api.galaxy.lan + ▼ +host-Caddy (:80, :443, TLS, attached to `edge` network) + │ reverse_proxy *.galaxy.lan → galaxy-caddy:80 + ▼ +galaxy-caddy (networks: edge + galaxy-dev-internal) + │ www.galaxy.lan → file_server /srv/galaxy-ui (volume galaxy-dev-ui-dist) + │ api.galaxy.lan → reverse_proxy galaxy-api:8080 + ▼ +galaxy-dev-internal + ├─ galaxy-api (gateway: :8080 REST, :9090 gRPC) + ├─ galaxy-backend (backend: :8080 HTTP, :8081 gRPC push) + ├─ galaxy-postgres (postgres: :5432) + ├─ galaxy-redis (redis: :6379) + ├─ galaxy-mailpit (mailpit: :8025 UI, :1025 SMTP) + └─ engine containers (spawned by backend on demand) +``` + +The compose project deliberately exposes no host ports. Diagnostics +that used to go through `localhost:8025` etc. now go through the +container network: `docker compose -f tools/dev-deploy/docker-compose.yml +exec galaxy-mailpit wget -qO- localhost:8025/messages` and similar. + +## Persistent state and schema changes + +The dev Postgres volume `galaxy-dev-postgres-data` survives redeploys. +Until the pre-production migration rule is lifted, every +backward-incompatible change to `backend/internal/postgres/migrations/00001_init.sql` +needs a manual wipe before the next deploy succeeds: + +```sh +make -C tools/dev-deploy clean-data +make -C tools/dev-deploy up +``` + +This is the same caveat as `tools/local-dev/`, just with a different +volume name. + +## Make targets + +```text +make up Build images, ensure engine image, bring stack up (waits for health) +make rebuild Rebuild backend / gateway images (ignores cache), then up +make seed-ui pnpm build + load build/ into galaxy-dev-ui-dist volume +make build-engine Build galaxy-engine:dev (no-op if image already present) +make down Stop containers, keep named volumes +make logs Tail compose logs +make status docker compose ps +make health curl https://www.galaxy.lan + https://api.galaxy.lan/healthz +make psql psql as galaxy@galaxy_backend +make clean-data Stop everything and wipe volumes + game-state dir +``` + +## Files + +- `docker-compose.yml` — six services: postgres, redis, mailpit, + galaxy-backend, galaxy-api, galaxy-caddy. Reuses the alpine-runtime + Dockerfiles from `../local-dev/` so the backend healthcheck can run + `wget`. Reuses the dev keypair from `../local-dev/keys/`. +- `Caddyfile.dev` — the application-routing Caddy config, mounted into + `galaxy-caddy` at `/etc/caddy/Caddyfile`. +- `Caddyfile.prod` — placeholder for a future prod deployment; not used + by this compose. +- `Makefile` — wrapper over `docker compose` with helpers for engine, + UI seeding, health probes, and full wipe. +- `.env.example` — non-secret defaults for the compose `${VAR:-}` + expansions. Copy to `.env` if you want host-local overrides. + +## Relationship to other infrastructure + +- `tools/local-dev/` — single-developer playground, host-port mapped, + Vite dev server on the side. Recommended for active UI work. +- `tools/local-ci/` — Gitea + act runner for **fallback** workflow + testing without `gitea.lan`. Optional, not part of the per-stage CI + gate anymore. +- `.gitea/workflows/dev-deploy.yaml` — the CI side of this stack: + builds images, seeds the UI volume, runs `docker compose up -d` on + every merge into `development`. The Makefile in this directory is + what that workflow ultimately calls into. diff --git a/tools/dev-deploy/docker-compose.yml b/tools/dev-deploy/docker-compose.yml new file mode 100644 index 0000000..5a449df --- /dev/null +++ b/tools/dev-deploy/docker-compose.yml @@ -0,0 +1,223 @@ +# Long-lived dev environment for the Galaxy stack, deployed by the +# `dev-deploy.yaml` Gitea Actions workflow on every merge into the +# `development` branch and (optionally) by `make -C tools/dev-deploy up` +# from a developer shell on the same host. +# +# The stack is reachable from a browser only through the host Caddy on +# the machine, which terminates TLS and forwards `*.galaxy.lan` into the +# external `edge` Docker network where `galaxy-caddy` does app-routing. +# No service in this compose project binds a host port — coexistence +# with `tools/local-dev/` (which listens on localhost:5433/6380/8025/...) +# is achieved by distinct names, networks, and volumes. +# +# Browser → host-Caddy (:80/:443) → galaxy-caddy → {galaxy-api, /srv/galaxy-ui} +# +# Persistent state lives in named volumes under the `galaxy-dev-*` +# prefix; surviving redeploys across compose rebuilds. + +name: galaxy-dev + +services: + galaxy-postgres: + image: postgres:16-alpine + container_name: galaxy-dev-postgres + restart: unless-stopped + environment: + POSTGRES_USER: galaxy + POSTGRES_PASSWORD: galaxy + POSTGRES_DB: galaxy_backend + volumes: + - galaxy-dev-postgres-data:/var/lib/postgresql/data + networks: + - galaxy-internal + healthcheck: + test: ["CMD-SHELL", "pg_isready -U galaxy -d galaxy_backend"] + interval: 3s + timeout: 3s + retries: 30 + start_period: 5s + + galaxy-redis: + image: redis:7-alpine + container_name: galaxy-dev-redis + restart: unless-stopped + command: + - redis-server + - --requirepass + - galaxy-dev + - --appendonly + - "no" + - --save + - "" + networks: + - galaxy-internal + healthcheck: + test: ["CMD", "redis-cli", "-a", "galaxy-dev", "PING"] + interval: 3s + timeout: 3s + retries: 30 + start_period: 3s + + galaxy-mailpit: + image: axllent/mailpit:v1.21 + container_name: galaxy-dev-mailpit + restart: unless-stopped + networks: + - galaxy-internal + healthcheck: + test: ["CMD", "wget", "-q", "-O-", "http://localhost:8025/livez"] + interval: 3s + timeout: 3s + retries: 30 + start_period: 3s + + galaxy-backend: + build: + context: ../.. + dockerfile: tools/local-dev/backend.Dockerfile + image: galaxy/backend:dev + container_name: galaxy-dev-backend + restart: unless-stopped + user: "0:0" + depends_on: + galaxy-postgres: + condition: service_healthy + galaxy-mailpit: + condition: service_healthy + environment: + BACKEND_LOGGING_LEVEL: info + BACKEND_HTTP_LISTEN_ADDR: ":8080" + BACKEND_GRPC_PUSH_LISTEN_ADDR: ":8081" + BACKEND_POSTGRES_DSN: "postgres://galaxy:galaxy@galaxy-postgres:5432/galaxy_backend?search_path=backend&sslmode=disable" + BACKEND_SMTP_HOST: galaxy-mailpit + BACKEND_SMTP_PORT: "1025" + BACKEND_SMTP_FROM: "galaxy-backend@galaxy.lan" + BACKEND_SMTP_TLS_MODE: none + BACKEND_DOCKER_NETWORK: galaxy-dev-internal + BACKEND_GAME_STATE_ROOT: ${GALAXY_DEV_GAME_STATE_DIR} + BACKEND_GEOIP_DB_PATH: /var/lib/galaxy/geoip.mmdb + BACKEND_NOTIFICATION_ADMIN_EMAIL: admin@galaxy.lan + BACKEND_MAIL_WORKER_INTERVAL: 500ms + BACKEND_NOTIFICATION_WORKER_INTERVAL: 500ms + BACKEND_OTEL_TRACES_EXPORTER: none + BACKEND_OTEL_METRICS_EXPORTER: none + BACKEND_AUTH_DEV_FIXED_CODE: ${BACKEND_AUTH_DEV_FIXED_CODE:-} + BACKEND_DEV_SANDBOX_EMAIL: ${BACKEND_DEV_SANDBOX_EMAIL:-} + BACKEND_DEV_SANDBOX_ENGINE_IMAGE: ${BACKEND_DEV_SANDBOX_ENGINE_IMAGE:-galaxy-engine:dev} + BACKEND_DEV_SANDBOX_ENGINE_VERSION: ${BACKEND_DEV_SANDBOX_ENGINE_VERSION:-0.1.0} + BACKEND_DEV_SANDBOX_PLAYER_COUNT: ${BACKEND_DEV_SANDBOX_PLAYER_COUNT:-20} + volumes: + - /var/run/docker.sock:/var/run/docker.sock + # Per-game state directories live under the same absolute path + # both inside the backend container and on the Docker daemon host, + # so the bind-mount source the backend hands to the daemon + # resolves correctly when spawning engine containers. The dev + # environment uses a distinct prefix from `tools/local-dev/` so + # the two stacks do not collide on the same host. + # Game-state root must resolve to the same absolute path inside + # the backend container and on the Docker daemon host, because + # backend hands that path to the daemon when it spawns engine + # containers. The Makefile exports `GALAXY_DEV_GAME_STATE_DIR` + # to `${HOME}/.galaxy-dev/game-state` by default, so a non-root + # runner user can write to it without sudo. + - type: bind + source: ${GALAXY_DEV_GAME_STATE_DIR} + target: ${GALAXY_DEV_GAME_STATE_DIR} + bind: + create_host_path: true + - ../../pkg/geoip/test-data/test-data/GeoIP2-Country-Test.mmdb:/var/lib/galaxy/geoip.mmdb:ro + networks: + - galaxy-internal + healthcheck: + test: ["CMD", "wget", "-q", "-O-", "http://localhost:8080/healthz"] + interval: 3s + timeout: 3s + retries: 60 + start_period: 10s + + galaxy-api: + build: + context: ../.. + dockerfile: tools/local-dev/gateway.Dockerfile + image: galaxy/gateway:dev + container_name: galaxy-dev-api + restart: unless-stopped + depends_on: + galaxy-backend: + condition: service_healthy + galaxy-redis: + condition: service_healthy + environment: + GATEWAY_LOG_LEVEL: info + GATEWAY_PUBLIC_HTTP_ADDR: ":8080" + GATEWAY_AUTHENTICATED_GRPC_ADDR: ":9090" + GATEWAY_BACKEND_HTTP_URL: "http://galaxy-backend:8080" + GATEWAY_BACKEND_GRPC_PUSH_URL: "galaxy-backend:8081" + GATEWAY_BACKEND_GATEWAY_CLIENT_ID: dev-gateway-1 + GATEWAY_RESPONSE_SIGNER_PRIVATE_KEY_PEM_PATH: /run/secrets/gateway-response.pem + GATEWAY_REDIS_MASTER_ADDR: "galaxy-redis:6379" + GATEWAY_REDIS_PASSWORD: galaxy-dev + # Anti-abuse defaults are looser than production: the dev + # environment is shared by a handful of trusted testers who + # frequently hammer the same identity to reproduce flows. + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_PUBLIC_AUTH_RATE_LIMIT_REQUESTS: "10000" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_PUBLIC_AUTH_RATE_LIMIT_BURST: "1000" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_SEND_EMAIL_CODE_IDENTITY_RATE_LIMIT_REQUESTS: "10000" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_SEND_EMAIL_CODE_IDENTITY_RATE_LIMIT_BURST: "1000" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_CONFIRM_EMAIL_CODE_IDENTITY_RATE_LIMIT_REQUESTS: "10000" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_CONFIRM_EMAIL_CODE_IDENTITY_RATE_LIMIT_BURST: "1000" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_PUBLIC_MISC_MAX_BODY_BYTES: "131072" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_PUBLIC_MISC_RATE_LIMIT_REQUESTS: "10000" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_PUBLIC_MISC_RATE_LIMIT_BURST: "1000" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_BROWSER_BOOTSTRAP_MAX_BODY_BYTES: "65536" + GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_BROWSER_ASSET_MAX_BODY_BYTES: "65536" + GATEWAY_AUTHENTICATED_GRPC_ANTI_ABUSE_IP_RATE_LIMIT_REQUESTS: "10000" + GATEWAY_AUTHENTICATED_GRPC_ANTI_ABUSE_IP_RATE_LIMIT_BURST: "1000" + GATEWAY_AUTHENTICATED_GRPC_ANTI_ABUSE_SESSION_RATE_LIMIT_REQUESTS: "10000" + GATEWAY_AUTHENTICATED_GRPC_ANTI_ABUSE_SESSION_RATE_LIMIT_BURST: "1000" + GATEWAY_AUTHENTICATED_GRPC_ANTI_ABUSE_USER_RATE_LIMIT_REQUESTS: "10000" + GATEWAY_AUTHENTICATED_GRPC_ANTI_ABUSE_USER_RATE_LIMIT_BURST: "1000" + GATEWAY_AUTHENTICATED_GRPC_ANTI_ABUSE_MESSAGE_CLASS_RATE_LIMIT_REQUESTS: "10000" + GATEWAY_AUTHENTICATED_GRPC_ANTI_ABUSE_MESSAGE_CLASS_RATE_LIMIT_BURST: "1000" + volumes: + - ../local-dev/keys/gateway-response.pem:/run/secrets/gateway-response.pem:ro + networks: + - galaxy-internal + healthcheck: + test: ["CMD", "wget", "-q", "-O-", "http://localhost:8080/healthz"] + interval: 3s + timeout: 3s + retries: 30 + start_period: 5s + + galaxy-caddy: + image: caddy:2.11.2-alpine + container_name: galaxy-dev-caddy + restart: unless-stopped + depends_on: + galaxy-api: + condition: service_healthy + volumes: + - ./Caddyfile.dev:/etc/caddy/Caddyfile:ro + - galaxy-dev-caddy-data:/data + - galaxy-dev-ui-dist:/srv/galaxy-ui:ro + networks: + - galaxy-internal + - edge + +networks: + galaxy-internal: + name: galaxy-dev-internal + driver: bridge + internal: false + edge: + name: ${GALAXY_EDGE_NETWORK:-edge} + external: true + +volumes: + galaxy-dev-postgres-data: + name: galaxy-dev-postgres-data + galaxy-dev-caddy-data: + name: galaxy-dev-caddy-data + galaxy-dev-ui-dist: + name: galaxy-dev-ui-dist