Wargrid Deployment
This page describes the checked-in deployment topology, the staging rollout, and the production promotion path.
Physical Hosts
94.16.119.228is the main server89.58.62.101is the first dedicated multiplayer node
Production Hosts And Domains
wargrid.appfor marketing and legalplay.wargrid.appfor the game clientapi.wargrid.appfor the Elysia and Better Auth surfacedocs.wargrid.appfor Docusaurus docswargrid.blogfor the Astro blogadmin.wargrid.appfor admin and moderation
Staging Hosts
Staging runs on the main server and uses a separate naming scheme that works with the configured wildcard DNS:
staging.wargrid.appstaging-play.wargrid.appstaging-api.wargrid.appstaging-admin.wargrid.appstaging-docs.wargrid.appstaging-blog.wargrid.appstaging-multiplayer.wargrid.app
Deploy Tooling
- GitHub Actions runs Bun and Turbo tasks
- GitHub Actions installs Node 22 before browser E2E so Playwright runs through the shared Node launcher on the self-hosted runner
- Kamal deploys the host-bound services from
infra/kamal/deploy.<service>.yml - multiplayer remains Bun-first with documented Node fallback only if Colyseus requires it
infra/docker/workspace-app.Dockerfileis the shared application image templateinfra/docker/entrypoint.shwraps each service with nginx and optional staging basic auth- the docs container uses
serve:prod:container, while local docs commands stay on127.0.0.1
Release Paths
Pull Request To Staging
CI in .github/workflows/ci.yml runs:
validate- the per-app
e2ematrix deploy-stagingfor non-draft pull requests from the same repository
deploy-staging installs Kamal, boots required accessories, clones the production database into wargrid_staging, deploys the full stack, and comments the staging URLs on the pull request.
Main To Production
Deploy Wargrid in .github/workflows/deploy-wargrid.yml runs on push to main and workflow_dispatch.
It repeats the full workspace validation, runs the root E2E suite, and then deploys the production stack.
Data And Migration Flow
- Postgres and Redis run as Kamal accessories on the main server.
- Staging uses the
wargrid_stagingPostgres database and a separate Redis logical database. infra/scripts/clone-staging-db.shrebuildswargrid_stagingfrom the production database before every staging rollout.infra/scripts/deploy-stack.shrunsbun run --cwd packages/db db:pushinside the API container after the API deploy completes.
Basic Auth On Staging
Staging is protected at the nginx layer with basic auth.
- Runtime flag:
BASIC_AUTH_ENABLED=true - Secret:
STAGING_BASIC_AUTH_PASSWORD - Username default:
wargrid
Keep the password in GitHub Actions secrets and local environment only. Do not commit it into the repository.
Required Secrets
GitHub Actions expects:
KAMAL_SSH_PRIVATE_KEYWARGRID_DATABASE_PASSWORDBETTER_AUTH_SECRETSMTP_PASSSTAGING_BASIC_AUTH_PASSWORD
During CI deploys, the workflows write .kamal/secrets-common on the runner from the GitHub secrets above. Staging also writes .kamal/secrets.staging for STAGING_BASIC_AUTH_PASSWORD. Those files stay untracked because .kamal/ is ignored.
GitHub Container Registry pushes use ${{ github.token }} together with workflow permission packages: write.
The current CI and deploy jobs run on the self-hosted runner wargrid-deploy-94 on 94.16.119.228. The runner labels are self-hosted, Linux, X64, and wargrid-deploy.
The deploy workflows also pin the target servers into ~/.ssh/known_hosts with ssh-keyscan -t ed25519 before Kamal connects. If a server is reprovisioned and its SSH host key changes, update the workflow expectations and re-run staging before promoting to production.
Post-Deploy Verification
Both deploy workflows call infra/scripts/verify-http-surface.mjs after the Kamal rollout finishes.
stagingverifies all staging hosts behind basic auth plus the direct staging API.productionverifies the public site, play app, admin app, docs, blog, and API health endpoints.
Keep this smoke current whenever hosts, routes, or expected landing-page text change.
Required Release Hygiene
Every release should update:
- docs
- AI notes if workflow changed
- changelog or release notes
- blog post planning for user-visible releases
- staging verification notes when the deploy path or test path changed