Eight templates
WordPress Server. Nginx, PHP with the extensions WordPress requires, and MariaDB.
Laravel Server. Nginx, PHP with the extensions Laravel requires, Composer and Node.js, with optional MariaDB and Redis.
Node.js Server. Node.js from nodejs.org, PM2, and Nginx in front.
Python Production Stack. Python, Nginx, Gunicorn in the application’s own virtual environment, uv, Poetry or Pipenv, and a service account with a hardened systemd service for a FastAPI or Django app.
Nginx Reverse Proxy + Auto-Renewing SSL. Nginx in front of an app, API or container, a Let’s Encrypt certificate requested only after a dry run against the staging environment, renewal that reloads nginx, and a final check that renewal works.
CI/CD Self-Hosted Runner Host. Docker, the tools CI jobs expect, and GitHub Actions or GitLab runner accounts and files, with Fail2Ban and a firewall that allows only SSH by default.
Docker Host. Docker Engine from Docker’s own repositories, with the Compose plugin.
Monitoring Server. Prometheus, Node Exporter and Grafana in containers, reachable only from the server itself.
Steps run in order
Each step is a standard playbook with the same preflight, state checks and output. Steps run in order on each server. If a step fails, the remaining steps are skipped on that server and the run shows which step failed.
Every step checks that it supports the server before the run changes anything, so a template aimed at an unsupported distribution stops at the preflight.
Versioned templates
Each template has a version and change notes. A run records the template version and the values used for every step.
When you review a run later, it shows what actually ran on that day, not what the current version of the template contains.
What templates do not do
A template prepares the server. It does not deploy your application, create its databases or change your DNS. The Python Production Stack installs the service for your app and leaves it stopped until your code is in place, and the run ends with the steps that remain.
The reverse proxy template needs your domains to point at the server and ports 80 and 443 to be open before it runs. The CI runner template never registers a runner, because that takes a token the platform has no reason to hold; the run ends with the command to register on the server.
Because steps check before they act, running a template on a server that is already partly set up is safe. Completed steps are reported as already done.
Frequently asked questions
- Does a template deploy my application?
- No. The WordPress Server template prepares the server WordPress runs on, and the Python Production Stack sets up the service your app will run as without starting it. Deploying the code and configuring the site are up to you.
- Can I dry run a template?
- Yes. A dry run walks through every step on every selected server and reports what would change, without changing anything.
- What happens if a step fails?
- The remaining steps are skipped on that server, and the run shows the failed step and its output. Other servers continue according to the run strategy.
- Can I run a template on a server that is already set up?
- Yes. Each step checks the current state first, so anything already installed is reported as installed rather than installed again.
- Which distributions do templates support?
- Whatever their steps support. The Python, reverse proxy and CI runner templates start at Ubuntu 22.04 and Debian 12, templates that install PHP do not run on Amazon Linux, and the preflight reports any step that does not support a server.
Key points
- WordPress, Laravel, Node.js and Python app servers
- Reverse proxy with Let’s Encrypt, and CI runner hosts
- Steps run in order; a failure stops that server
- Template version recorded on every run
- Dry runs, canaries and batches like any other run