Production (shaops)¶
shaapi ops — shaops — turns the manual "ship it to a VPS" runbook into a
few commands. It only generates files you run yourself on the server; it
never connects out and never handles your credentials over the wire.
Secure by default¶
A generated project is hard to deploy insecurely:
- a production fail-fast guard refuses to boot (outside dev) while any development default secret remains;
- the container runs as a non-root user;
- in production the datastores publish no host ports — Postgres, Redis and MinIO are reachable only on the internal Docker network.
The dev / prod branch model¶
This scaffolds a git repository with two branches:
| Branch | Contents |
|---|---|
dev |
the lean development project (you start here) |
prod |
the same project plus the production config |
The application code (backend/) is identical on both branches — only the
config diverges (the prod compose overlay, env example, deploy scripts). You
ship by merging dev into prod; the VPS tracks prod. No code drift.
Already have a project? Run
shaapi ops hardento add the production config in place.
What shaapi ops harden writes¶
| File | Role |
|---|---|
docker-compose.prod.yml |
overlay: datastores publish no host ports, ENVIRONMENT=prod, a daily Postgres backup sidecar |
.env.prod.example |
the production env template (copy to .env on the server) |
deploy/provision.sh |
install Docker Engine + compose on Ubuntu/Debian |
deploy/harden-os.sh |
firewall (ufw: deny inbound except 22/80/443) + a port-exposure check |
Going live¶
# 1. On the server (one-time)
ssh root@your-vps 'bash -s' < deploy/provision.sh # install Docker
ssh root@your-vps 'bash -s' < deploy/harden-os.sh # firewall
# 2. Config (on the server)
cp .env.prod.example .env
shaapi ops secrets --write # generate + inject strong secrets into .env
# ... then set POSTGRES_PASSWORD / MINIO_SECRET_KEY as needed
# 3. Run the hardened stack
shaapi up --prod # loads docker-compose.prod.yml (datastores closed)
shaapi db apply # migrations
shaapi auth init # first admin
Put a reverse proxy (nginx / Caddy / Traefik) in front, terminating TLS on 443
and forwarding to the API on 127.0.0.1:8000.
shaapi ops checklist prints the full go-live checklist at any time.
Verify the hardening¶
shaapi sec ports your-vps # Postgres/MinIO must be CLOSED
ss -tulnp | grep -E ':(5432|9000)' # nothing on 0.0.0.0
See Security (shasec) to attack your own API and confirm it resists.