Skip to main content
Golden wattle in full bloom with bottlebrush spikes threaded through, in a three-ink risograph print

Running in production

A deployed system needs durable data, protected secrets and enough logging to diagnose failures without exposing its users

Production differs from your machine: a different filesystem and environment, a proxy in front of the app, and nobody watching each request. The mechanics of your Fly access — your token, the deploy command and the resource limits — are on your hosting access. The same production concerns apply if you change hosting providers.

The deployment contract

A repeatable deploy requires the complete recipe in the repository and the credential outside it.

A full-stack repo stores the recipe in three files:

Changing stack means changing the Dockerfile. The workflow and hosting configuration stay as they are, because neither names a stack. The static half uses the same separation through pnpm build and the dist/ directory.

A deploy step that ends when the image boots has proved only that the image boots. The course’s CI then checks for a 200 response and valid internal links, and the lecture demo adds probes for its event stream, an accepted same-origin POST and a refused cross-site one. Each check covers a production failure that local checks have missed.

Data and secrets

Two questions to be able to answer about a deployed app.

What survives a restart? On Fly, exactly one thing: the volume. The lecture demo’s SQLite file lives at /data/app.db on it, which is why a message posted before a redeploy is still there afterwards. Everything else — the container filesystem, anything held in a module-level variable, the set of open connections — is rebuilt from nothing every time the machine starts. Machines also stop when idle and start on the next request, so “every time” is more often than you think.

Check this explicitly. An app that writes outside the volume can work for an afternoon and lose the lot on the next deploy.

Where do secrets live? The dividing line in a server-rendered app is which side of the wire the code runs on. In an Astro page the frontmatter runs on the server and a <script> block is shipped to the browser, so a value read in one is private and the same value read in the other is public. Anything prefixed PUBLIC_ is in the client bundle by design.

Three rules cover the rest:

CI scans every commit in the history for committed credentials, so the cost of getting this wrong is a red run rather than a quiet leak — but only for secrets a scanner can recognise.

Useful instruments

Choose each instrument for a question you need to answer:

A dashboard of every available number does not answer these questions. For an app this size, a few targeted log lines are enough.