Fifteen steps, all re-runnable
Site name, domain, admin account, certificate, SSH key: everything is asked before starting, then summarised for confirmation. After that, nothing more to type. Every step is idempotent — if one fails, you fix the cause and run the same command again, without undoing anything.
[00] Pre-flight checks
[01] Hardening: firewall, SSH, fail2ban, sysctl, auto-updates
[02] System account, directories and permissions
[03] System dependencies
[04] PostgreSQL — service and hardening
[05] Database and application role
[06] Memcached
[07] Python environment
[08] JEIKO package and update mechanism
[09] Django configuration (.env, settings, urls)
[10] Gunicorn service
[11] Nginx
[12] Let's Encrypt certificate and HTTPS
[13] Backups and monitoring
[14] Migrations, static files, health check
- Several sites per server. Each gets its own Unix account, database, service and backups; a flaw in one gives no access to the others.
- Secrets are generated, not chosen. Django's secret key and, if you leave the field empty, the PostgreSQL password (forty characters) are drawn at random. The admin account's password is used once and stored nowhere.
- The admin account can sign in right away: its address is recorded as verified in the last step.