Skip to main content

Wargrid Deployment

This page describes the checked-in deployment topology, the staging rollout, and the production promotion path.

Physical Hosts

  • 94.16.119.228 is the main server
  • 89.58.62.101 is the first dedicated multiplayer node

Production Hosts And Domains

  • wargrid.app for marketing and legal
  • play.wargrid.app for the game client
  • api.wargrid.app for the Elysia and Better Auth surface
  • docs.wargrid.app for Docusaurus docs
  • wargrid.blog for the Astro blog
  • admin.wargrid.app for 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.app
  • staging-play.wargrid.app
  • staging-api.wargrid.app
  • staging-admin.wargrid.app
  • staging-docs.wargrid.app
  • staging-blog.wargrid.app
  • staging-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.Dockerfile is the shared application image template
  • infra/docker/entrypoint.sh wraps each service with nginx and optional staging basic auth
  • the docs container uses serve:prod:container, while local docs commands stay on 127.0.0.1

Release Paths

Pull Request To Staging

CI in .github/workflows/ci.yml runs:

  1. validate
  2. the per-app e2e matrix
  3. deploy-staging for 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_staging Postgres database and a separate Redis logical database.
  • infra/scripts/clone-staging-db.sh rebuilds wargrid_staging from the production database before every staging rollout.
  • infra/scripts/deploy-stack.sh runs bun run --cwd packages/db db:push inside 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_KEY
  • WARGRID_DATABASE_PASSWORD
  • BETTER_AUTH_SECRET
  • SMTP_PASS
  • STAGING_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.

  • staging verifies all staging hosts behind basic auth plus the direct staging API.
  • production verifies 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