Skip to main content

Provisioning a Circus Server

This is the groundwork: taking a fresh server to the point where a deploy can land on it. The reference setup runs both staging and production on one host, each with its own API, frontend, Postgres, and n8n, behind a shared Caddy — so plan for a machine that can hold two environments (the guide targets Ubuntu 24.04 LTS, ~8 GB RAM / 2 CPU minimum).

The deploy user

Don't deploy as root. Create a dedicated deploy user, give it sudo (temporarily — you'll tighten this during hardening), and set up its ~/.ssh. CI will SSH in as this user.

Docker

Install Docker Engine (curl -fsSL https://get.docker.com | sh) and add deploy to the docker group so it runs Docker without sudo. Log out and back in for the group change to take effect, then confirm docker ps works.

App directories and the permanent networks

Create the environment directories and hand them to deploy:

sudo mkdir -p /app/staging /app/production
sudo chown -R deploy:deploy /app

Then create the two permanent Docker networks — infrastructure that exists before any deploy:

docker network create staging_default
docker network create production_default

Each environment's compose stack declares its network as external, and the shared Caddy joins both networks to route traffic. This is what keeps staging and production isolated on one host — which is also why every compose command uses a -p staging / -p production project flag (see Day-2 Operations).

DNS

Point four A-records at the server IP — the app and n8n domains for each environment:

staging.circus.sh A YOUR_IP
n8n-staging.circus.sh A YOUR_IP
demo.circus.sh A YOUR_IP
n8n-demo.circus.sh A YOUR_IP

(Propagation can take minutes to hours.) With the user, Docker, directories, networks, and DNS in place, the host is ready — next come the environment files and the reverse proxy.