Twelve-factor apps

The Twelve-Factor App is a methodology Adam Wiggins and colleagues at Heroku wrote down for building services that are easy to deploy, scale and hand over. It was written for the cloud, but it fits a single self-hosted machine just as well. Every project here follows it; this is our reading of each factor for a Ruby stack run by systemd with ngrok in front.

Why it suits us

Twelve-factor apps keep the parts that change (config, backing services, the machine) outside the code. That is the same idea as owning your stack: when a database, an AI model or a host is attached by a URL in config, swapping it is an edit to .env, not a rewrite.

The twelve factors, our way

  1. Codebase. One git repository per project, and every deploy comes from it.
  2. Dependencies. Declared in a Gemfile with a committed Gemfile.lock, run through bundle exec. Nothing works only because a gem happened to be installed system-wide.
  3. Config. Ports, URLs and secrets come from environment variables, loaded from the project's git-ignored .env (see Secrets). Code holds no settings that differ between machines.
  4. Backing services. Databases, local models, queues and outside APIs are attached by URL from config, so each one can be replaced without touching code.
  5. Build, release, run. Install dependencies, then start. Nobody edits code under a running service.
  6. Processes. Stateless. Anything that must survive a restart lives in a backing service or a data folder named in config, never only in memory.
  7. Port binding. Each app serves HTTP itself on a PORT from config, bound to 127.0.0.1. ngrok or another proxy is what makes it public.
  8. Concurrency. Scale out with more processes, each its own systemd unit, rather than one ever larger process.
  9. Disposability. Start in seconds, stop cleanly on SIGTERM, and be safe to restart at any moment. systemd restarts anything that falls over.
  10. Dev/prod parity. The same Ruby, the same gems and the same kinds of backing services in development and in production.
  11. Logs. One event per line on stdout. journald and the observability stack collect them; apps never manage their own log files.
  12. Admin processes. One-off tasks are scripts in the project's bin/, run with the same code and config as the app.

Where it's written down

These rules are section 14 of AGENTS.md, which every coding agent working here follows. A new project that breaks one of them needs a stated reason.


Provided as is, for information only, with no warranty and no liability. Not legal or professional advice. Security and radio material is for authorized, lawful use only. Full disclaimer.

Visits are logged on our own server: IP address, browser and device details, and pages viewed. We use them to understand traffic and spot attacks, and never share or sell them.