diff --git a/deploy/galactus/jorgecuadros-app.compose.yml b/deploy/galactus/jorgecuadros-app.compose.yml index f496965..e8b1275 100644 --- a/deploy/galactus/jorgecuadros-app.compose.yml +++ b/deploy/galactus/jorgecuadros-app.compose.yml @@ -11,6 +11,16 @@ # name galactus's own address and the published port — exactly as on cubex # today. Do not "simplify" them to `mysql:3306`. # +# ...which means these containers have to resolve galactus's MagicDNS name, and +# by default they CANNOT. The host runs systemd-resolved, whose 127.0.0.53 stub +# is unreachable from a container, so Docker falls back to the upstream resolver +# in /run/systemd/resolve/resolv.conf — the LAN router, which knows nothing +# about the tailnet. Routing to 100.x works fine; only the lookup fails, and the +# API dies with Prisma P1001 "can't reach database server". Pointing the +# containers at Tailscale's own resolver fixes it. 100.100.100.100 is Tailscale's +# fixed anycast MagicDNS address (identical on every tailnet); the search domain +# is this tailnet's suffix. +# # The web image is NOT URL-baked: the browser's API origin is injected at # runtime from API_ORIGIN (apps/web/src/app/layout.tsx), so the same image works # for any deployment. APP_VERSION / GIT_SHA / BUILD_DATE come baked in from @@ -27,6 +37,10 @@ services: # survives stack renames; the compose service name does not. labels: io.jorgecuadros.role: "api" + dns: + - ${TAILSCALE_DNS:-100.100.100.100} + dns_search: + - ${TAILNET_SUFFIX:-tail01aa2.ts.net} environment: DATABASE_URL: ${DATABASE_URL:?DATABASE_URL must be set} SESSION_SECRET: ${SESSION_SECRET:?SESSION_SECRET must be set} @@ -59,6 +73,12 @@ services: restart: unless-stopped labels: io.jorgecuadros.role: "web" + # Next server-side rendering can call the API by API_ORIGIN, which is the + # same MagicDNS name — so the web container needs the resolver too. + dns: + - ${TAILSCALE_DNS:-100.100.100.100} + dns_search: + - ${TAILNET_SUFFIX:-tail01aa2.ts.net} environment: # Public API URL the browser calls (injected at runtime, see layout.tsx). API_ORIGIN: ${API_ORIGIN:?API_ORIGIN must be set} diff --git a/docs/DEPLOY_AND_MIGRATIONS.md b/docs/DEPLOY_AND_MIGRATIONS.md index ba06f2c..50375c1 100644 --- a/docs/DEPLOY_AND_MIGRATIONS.md +++ b/docs/DEPLOY_AND_MIGRATIONS.md @@ -148,6 +148,30 @@ service DNS: db, minio and app are three separate stacks, so three separate networks. `DATABASE_URL` and `S3_ENDPOINT` name the host and its published port. Do not "simplify" them to `mysql:3306`. +### galactus is addressed by MagicDNS, and containers need help resolving it + +galactus is Tailscale-only once it is installed in the office, so every URL +names `galactus.tail01aa2.ts.net`. Its LAN IP is a DHCP lease and has already +drifted once — never put a `192.168.4.x` address in a secret. + +Containers on galactus cannot resolve that name by default. The host runs +systemd-resolved, whose `127.0.0.53` stub is unreachable from inside a +container, so Docker falls back to the upstream resolver listed in +`/run/systemd/resolve/resolv.conf` — the LAN router, which knows nothing about +the tailnet. Routing to `100.x` works fine; only the *lookup* fails, and the +symptom is Prisma **P1001 "can't reach database server"** on a container that +otherwise started cleanly. + +`deploy/galactus/jorgecuadros-app.compose.yml` therefore pins the resolver: + +```yaml +dns: [100.100.100.100] # Tailscale's fixed anycast MagicDNS address +dns_search: [tail01aa2.ts.net] # this tailnet's suffix +``` + +Both are overridable (`TAILSCALE_DNS`, `TAILNET_SUFFIX`) if the tailnet changes. +Browser-facing origins need none of this — those names resolve on the client. + ## Replication galactus's MySQL is the **master**; every other MySQL in the estate is a