diff --git a/hostinger/prod-stack.yaml b/hostinger/prod-stack.yaml index 87f675f..96c25e1 100644 --- a/hostinger/prod-stack.yaml +++ b/hostinger/prod-stack.yaml @@ -34,8 +34,8 @@ services: # Bee node that saw them knows how full a batch is. Sitting next to prod_bee # is what makes fullness, the bucket map and batch_full alerts possible. stamp-monitor: - image: ghcr.io/ffaerber/swarm-stamp-monitor@sha256:62cf97f72090879f8d470fc9f2a09ab60d1d3a29dd658dfe2cd3a313c2b23540 - networks: [internal] + image: ghcr.io/ffaerber/swarm-stamp-monitor@sha256:aebf7e471f41cfdf43f8b6bc8dcdba4d29bc277612a302f61b7ed805b243901c + networks: [internal, public] volumes: - stamp-monitor-data:/data env_file: @@ -72,6 +72,25 @@ services: limits: cpus: "0.30" memory: 256M + # Published at bee.t4t-gateway.com. The gateway's own /bee page shows a + # summary; this is the full view — batch fullness, the bucket map, wallet + # and chequebook runway, and the action ledger. + # + # Safe to publish because the app fails CLOSED, not because the network + # protects it: every /api/admin route requires an x-admin-token and + # returns 503 when ADMIN_TOKEN is unset, so a misconfigured deploy is a + # visible outage rather than an open door onto endpoints that buy postage. + # The Bee node itself stays unpublished — reaching it through here still + # needs that token, which is the point of putting the monitor in front. + labels: + - "traefik.enable=true" + - "traefik.docker.network=public" + - "traefik.constraint-label=public" + - "traefik.http.routers.stamp-monitor.rule=Host(`bee.t4t-gateway.com`)" + - "traefik.http.routers.stamp-monitor.entrypoints=websecure" + - "traefik.http.routers.stamp-monitor.tls.certresolver=le" + - "traefik.http.services.stamp-monitor.loadbalancer.server.port=3000" + - "traefik.http.routers.stamp-monitor.middlewares=redirect-to-https" frontend: image: ghcr.io/token-for-token/hosted-gateway-frontend:main diff --git a/hostinger/readme.md b/hostinger/readme.md index 010e1e1..90017c6 100644 --- a/hostinger/readme.md +++ b/hostinger/readme.md @@ -30,6 +30,7 @@ Point all of these at `195.35.25.26`: A t4t-gateway.com 195.35.25.26 A www.t4t-gateway.com 195.35.25.26 A api.t4t-gateway.com 195.35.25.26 +A bee.t4t-gateway.com 195.35.25.26 A dev.t4t-gateway.com 195.35.25.26 A traefik.t4t-gateway.com 195.35.25.26 A grafana.t4t-gateway.com 195.35.25.26 @@ -104,9 +105,19 @@ not on-chain** — postage stamps are off-chain signatures, so only a node that saw them knows how full a batch is. A batch can be fully funded and still refuse writes. -No Traefik route and no published port: it is on `internal` only, and its UI -can spend xBZZ. Note `internal` is **not attachable**, so `docker run --network -internal ...` is refused — query through a container that is already on it: +Published at **[bee.t4t-gateway.com](https://bee.t4t-gateway.com)**. The +gateway's own `/bee` page shows a summary; this is the full view — batch +fullness and the bucket map, wallet and chequebook runway, and the ledger of +every top-up it has made or refused. + +It is publishable because the app fails **closed**: every `/api/admin` route +requires an `x-admin-token` and returns 503 if `ADMIN_TOKEN` is unset, so a +misconfigured deploy is a visible outage rather than an open door onto +endpoints that spend xBZZ. The Bee node stays unpublished; reaching it through +the monitor's passthrough still requires that token. + +From the shell, note `internal` is **not attachable**, so `docker run --network +internal ...` is refused — query through a container already on it: ```bash docker service logs --tail 50 prod_stamp-monitor @@ -115,16 +126,6 @@ M=$(docker ps --filter name=prod_stamp-monitor -q | head -1) docker exec $M bun -e 'console.log(await (await fetch("http://bee:1633/stamps")).text())' ``` -For the dashboard, publish it only for as long as you are looking at it, and -tunnel rather than exposing the port — swarm ingress binds `0.0.0.0`, so a -published port is on the public internet: - -```bash -docker service update --publish-add published=8088,target=3000 prod_stamp-monitor -ssh -L 8088:127.0.0.1:8088 root@ # then http://127.0.0.1:8088 -docker service update --publish-rm published=8088,target=3000 prod_stamp-monitor -``` - The API authenticates with an **`x-admin-token`** header, not `Authorization: Bearer`. A wrong header is a 401; a missing `ADMIN_TOKEN` in the service is a 503 (`admin API disabled`) — it fails closed, because these routes buy postage.