How We Shipped a Bulletproof App Between Sunset and Sunrise
One night, two founders, and a cold server. Here is the exaggerated-but-true engineering log of taking a dusty VM to a hardened, multi-container production stack before sunrise.
00:00 — Waking a cold box
We started with a single Ubuntu 24.04 VM that had been idling for seven months. One sweep of apt applied 45 pending updates, we rebooted onto a fresh 6.8 kernel, and the machine was current to the minute.
00:30 — Hardening, as code
Everything went through Ansible roles, so it is reproducible rather than a snowflake. SSH dropped to key-only auth (PasswordAuthentication no, root prohibit-password), ufw defaulted to deny-inbound with only 22/80/443 open, fail2ban took the SSH jail, and unattended-upgrades kept security patches flowing. Within minutes fail2ban had already banned three brute-force IPs.
01:00 — Secrets in a vault
Plaintext credentials came out of the repository and into an ansible-vault (AES-256), rendered into .env only at deploy time. The server clones the private repo with a read-only deploy key — nothing sensitive lives in git anymore.
02:00 — A container fleet behind one proxy
Docker Compose brought up the whole stack: Django + Gunicorn, PostgreSQL, a Next.js standalone build, the embeddable consent widget on nginx, and Traefik out front. Traefik path-routes /api, /admin and /static to Django and everything else to Next.js, terminates TLS, and pulls Let’s Encrypt certificates automatically over the HTTP-01 challenge. Cloudflare handles DNS. Persistent volumes keep Postgres, the ACME certs, and user uploads alive across redeploys.
03:00 — Make it observable
Sentry is wired for error tracking with PII off and request bodies never captured (it is a GDPR product, after all). Add a real health endpoint, a CI pipeline running pytest and tsc, and idempotent Ansible, and the next deploy collapses to one command: clone, render env, build, migrate, collectstatic, restart.
Sunrise — the numbers
By morning: a five-service stack, TLS end to end, automated certificate renewal, encrypted secrets, automatic security updates, and a one-command repeatable deploy — built in a single night, by two people, with zero hand-tuned server snowflakes. We may have over-engineered it for a v0. We regret nothing.
