939612f089fdf485f57c5e0876bb3193018c217d
GITHUB_TOKEN expires with the workflow run, but `docker login` writes it to /root/.docker/config.json on the host, where it stays. Docker then presents that dead token on every subsequent pull and does NOT fall back to anonymous, so even a public image fails with "No such image" -- which reads as a missing image rather than a stale credential. This broke deploys of services that have nothing to do with this workflow. The workaround each time was to delete the ghcr.io auth entry by hand, pull, and restore it; the stale entry has now been removed from the host as well. Uses a trap on EXIT rather than a trailing command so the logout also runs when a pull or a stack deploy fails -- the failure case is exactly when a half-finished run would otherwise leave the credential behind. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YLYiaPYror1vLKApYKrxTu
DevOps
This repo manages the two environments for the Token4Token hosted gateway:
local/— docker-compose files for running development and testing environments locally. Tests run inside Docker, no host-side Bun needed.hostinger/— Docker Swarm stack files for the remote production cluster on Hostinger.
The layout mirrors cipherdolls/devops.
Local development
cd local
make up # bring the dev stack up (postgres, redis, bee, anvil, api, worker)
make logs # tail
make down # clean shutdown
The dev compose mounts ../../hosted-gateway/src so file changes hot-reload
inside the container (bun run --watch).
Local testing
Every E2E spec runs inside Docker against a fresh stack (anvil fork of Gnosis, deployed contracts, a t4t-provider container against a stub Ollama).
cd local
make test SPEC=accounts # run one spec
make test-all # run every spec sequentially
make test brings up postgres + redis + anvil + bee + t4t-provider + hosted
api + worker, then runs the bun test container against them. After the run
it tears everything down (-v --remove-orphans).
Hostinger / production
Stack files in hostinger/ are applied via docker stack deploy from the CI
pipeline. Not relevant for local development.
Languages
Makefile
77.2%
TypeScript
18.7%
Dockerfile
4.1%