Rafif Dzaky
Open to DevOps roles

Docs · ~/work/pit-wall-on-call

Work 04 · Pit Wall On-Call

Pit Wall On-Call, a game I build and run in production

A browser game about being on call, built and run by me. Every merge is tested, shipped as SHA-tagged images and deployed to my homelab. A bad release rolls back on its own, and a game day on 28 Sep 2026 proved it.

Context
Personal project · live at pitwall.rafifdzaky.com
Period
Sep 2026 – present
Role
Sole author. I designed the game, wrote the code and run the infrastructure it lives on.
Stack
  • TypeScript
  • React
  • Hono
  • PostgreSQL
  • Docker
  • GitHub Actions
  • GHCR
  • Tailscale
  • Cloudflare Tunnel
  • Caddy
  • Playwright

Case study

What it is

You get paged, dig through monitoring, logs, deploys and chat, and fix the cause before the error budget runs out. Then you read a postmortem of your shift. The nine incidents come from real public postmortems: a leaking connection pool, a full disk, an expired certificate, a retry storm, replica lag and more.

The café scene at the start of a shift in Jakarta: a laptop showing a 504 Gateway Timeout page, a phone on the table with a page, street shops outside the window
Each shift starts in a café in Jakarta. The phone on the table has the page.
The Monitoring app during CPU saturation: three alerts, a service map with edge-gateway and search-api critical, a 5xx rate of 17.3 percent, and upstream timeouts in the log stream
Monitoring during CPU saturation. Search times out because one regex pins the search API at full CPU.
The Monitoring app during a full disk: three alerts including NodeDiskFull, a service map with edge-gateway and checkout-api critical, a 5xx rate of 34.9 percent, and checkout 500 errors in the log stream
Monitoring during a full disk. Checkout fails because /var/log filled up on one API node.

How it ships

  • Pull request: lint, type checks, 700+ tests, Playwright, shellcheck and tests for the deploy script. Both Docker images build.
  • Merge to main: API and web images are tagged with the commit SHA and pushed to GHCR.
  • Deploy: the job joins my tailnet with a tag that reaches one host on port 22, and runs deploy.sh. Players come in through a Cloudflare Tunnel, so no port is open at home.
  • deploy.sh: migrates the database, starts the release, replays a known game through the whole stack as a smoke test, and rolls back to the last good release if anything fails.

Game day, 28 September 2026

I merged a release whose readiness check always failed, with the hypotheses written in the pull request first.

Hypothesis Result Evidence
The smoke test rejects the broken release Pass smoke test failed for 5d73169
deploy.sh rolls back to the last good release Pass rollback ok: fd8bcf9
The deploy job goes red Pass exit code 1
Players see no impact Pass the site served fd8bcf9 throughout

Only the API and web containers were recreated. Postgres kept running. The revert went out as a normal pull request and deployed green.

Scores the browser can’t fake

Each run is a seed plus a list of actions. The API replays the list with the same deterministic engine and stores its own score. The browser’s score is ignored, and impossible actions are rejected.

What I’d do next

  • A public status page for the game, fed by the checks that gate the deploy.
  • An SSH forced command for the deploy user, so the CI key can only run the deploy script.

Play it · Source code · Runbook

recruiter@rafifdzaky: ~

Exec summary · 60 seconds

Rafif Dzaky Daniswara, DevOps Engineer

I own everything after the merge for PT PSM's 20+ production services: the pipelines that ship them, the servers they run on, and the monitoring that tells me when something drifts.

What I own today

  • CI/CD and release approvals
  • Linode VPS fleet: setup, scaling, hardening
  • Domains, DNS and SSL
  • Access, IAM and secrets
  • Monitoring and incident response

Not yet (learning in my homelab)

  • Kubernetes in production
  • AWS or GCP at scale

Evidence

Email [email protected]Contact detailsRésumé