Aller au contenu

Initialization

Overview

setup.sh is the single entry point for provisioning a server — whether from scratch or recovering from a failure. It handles Docker, security hardening, directory structure, secrets, networks, shared services, nginx, monitoring, Umami, and the docs site.

There are also per-service bootstrap targets (helios-init, umami-init, docs-init) for adding services to an already-running server.

Setup Modes

Fresh install

For a brand new server with no existing data.

cd /opt/docker/aether/repo
sudo ./setup.sh              # interactive — choose option 1
sudo ./setup.sh --fresh      # non-interactive

What it does:

  • Generates new passwords for all databases and Django SECRET_KEYs
  • Creates PostgreSQL init script with generated credentials
  • Prompts for basic auth username/password (staging/dev)
  • Generates a new age keypair for secret encryption
  • Encrypts all secrets into .enc files (commit and push these)

After completion:

  1. Save the age private key from /opt/docker/.age-key.txt to the password manager
  2. Edit env files for external services (SMTP, Sentry, API keys)
  3. Clone app repos and deploy (see post-setup checklist below)
  4. Commit and push the .enc files

Server migration / recovery

For rebuilding from an existing deployment with encrypted secrets in git.

cd /opt/docker/aether/repo
sudo ./setup.sh                                  # interactive — choose option 2, paste age key
sudo ./setup.sh --recover AGE-SECRET-KEY-...     # non-interactive

What it does:

  • Writes the age key to /opt/docker/.age-key.txt
  • Decrypts all .enc files to their server locations (make decrypt)
  • All existing passwords and credentials are restored (database dumps will work)

After completion: restore databases and media, clone app repos, deploy. See disaster recovery for the full procedure.

What Setup Handles

Step What Notes
1 Docker CE Installs + enables, adds debian to docker group
2 Utilities git, apache2-utils, cron, fail2ban, iptables-persistent, age, sops
3 Swap 11 GB swap file, vm.swappiness=10
4 Unattended upgrades Automatic Debian security patches
5 SSH hardening Port 57361, key-only auth (checks for keys first)
6 Firewall systemd service applying iptables after Docker starts
7 fail2ban sshd + 4 nginx jails
8 Kernel hardening rp_filter, log_martians via sysctl
9 Directory structure All /opt/docker/ directories
10 Config deployment make deploy — all configs copied to server
11 Secrets Fresh: generate. Recovery: decrypt from .enc files
12 Docker networks backend, web, monitoring
13 Shared services PostgreSQL + Redis started, readiness check
14 Static volumes aletheia-{prod,staging,dev}-static
15 Nginx Started in maintenance mode (.conf.temp)
16 SSL certificates Certbot for all *.groupe-suffren.com domains, then activates .conf.full
17 Monitoring + Umami + Docs All started
18 Firewall rules Applied after Docker is running
19 Backup cron Daily at 02:00
20 Encrypt (fresh only) Encrypts generated secrets into .enc files

Bootstrap Targets

These are for adding a specific service to an already-running server.

helios-init

Bootstraps Helios directories, env files, nginx configs, and monitoring rules.

cd /opt/docker/aether/repo && make helios-init

What it does:

  1. Creates /opt/docker/helios/{repo,envs}/
  2. Generates .env.{prod,staging,dev} with new REVALIDATION_SECRET values
  3. Deploys Helios nginx configs (.conf.full and .conf.temp)
  4. Deploys Helios monitoring rules (helios.rules.yml)
  5. Reloads nginx and Prometheus

After completion:

  • Copy the printed REVALIDATION_SECRET values into the matching Aletheia env files
  • Clone the Helios repo to /opt/docker/helios/repo/
  • Run make encrypt to persist the new secrets
  • Obtain SSL certificates for practice domains (not handled by setup.sh)

umami-init

Bootstraps Umami analytics from scratch — database, container, SSL, nginx.

cd /opt/docker/aether/repo && make umami-init

What it does (7 steps):

  1. Creates directories, deploys docker-compose and nginx configs
  2. Creates umami database and user in PostgreSQL
  3. Activates temp nginx config (HTTP only)
  4. Obtains SSL certificate for analytics.groupe-suffren.com
  5. Activates full nginx config (HTTPS)
  6. Starts the Umami container
  7. Verifies the container is running

After completion:

  • Visit https://analytics.groupe-suffren.com
  • Change the default password (default: admin / umami)
  • Add websites and note the UUIDs for Helios env vars
  • Run make encrypt to persist the .env

docs-init

Bootstraps the Mnemosyne documentation site — venv, build, SSL, nginx.

cd /opt/docker/aether/repo && make docs-init

What it does (5 steps):

  1. Creates /opt/docker/mnemosyne/, installs MkDocs Material in a venv
  2. Assembles docs from all repos and builds the static site
  3. Deploys nginx configs, starts nginx with temp config
  4. Obtains SSL certificate for docs.groupe-suffren.com
  5. Activates full nginx config (HTTPS)

After completion: site is live at https://docs.groupe-suffren.com. Rebuild with make docs-build, test locally with make docs-serve (port 8888).

Post-Setup Checklist

Fresh install

  • [ ] Reconnect via new SSH port: ssh -p 57361 debian@<server-ip>
  • [ ] Save age key to password manager: cat /opt/docker/.age-key.txt
  • [ ] Edit env files for external services (SMTP, Sentry, Teams webhook):
    • /opt/docker/aletheia/envs/.env.prod
    • /opt/docker/monitoring/.env
  • [ ] Clone app repos and deploy:
    • git clone git@github.com:baudry-suffren/aletheia_v2.git /opt/docker/aletheia/repo
    • git clone git@github.com:baudry-suffren/helios.git /opt/docker/helios/repo
  • [ ] Create Django superuser: docker exec -it aletheia-prod-web python manage.py createsuperuser
  • [ ] Change Umami default password at https://analytics.groupe-suffren.com
  • [ ] Commit and push .enc files from the aether repo
  • [ ] Test backup cron: /opt/docker/backups/scripts/backup.sh
  • [ ] Verify all environments accessible in browser
  • [ ] Check make diff shows no drift

Recovery

  • [ ] Reconnect via SSH port 57361
  • [ ] Verify secrets decrypted: ls /opt/docker/shared/.env /opt/docker/aletheia/envs/.env.prod
  • [ ] Restore databases from backup (see disaster recovery)
  • [ ] Restore media files
  • [ ] Clone app repos and deploy
  • [ ] Verify all environments accessible
  • [ ] Check make diff shows no drift
  • [ ] Verify backup cron is installed: crontab -l | grep backup

Troubleshooting

setup.sh fails at Docker install: Check internet connectivity and Debian version. Docker CE requires Debian 12+.

SSL certificates fail: DNS must point to the server before certbot can validate. Check with dig +short <domain>. Sites remain in HTTP maintenance mode until certs are obtained. Retry manually:

docker exec certbot certbot certonly --webroot -w /var/www/certbot \
  --non-interactive --agree-tos --email admin@groupe-suffren.com -d <domain>

PostgreSQL fails to start: Check if port 5432 is already in use: ss -tlnp | grep 5432. Check logs: docker logs shared_postgres.

"Permission denied" on env files: Env files should be owned by debian:debian with mode 600. Fix:

sudo chown debian:debian /opt/docker/aletheia/envs/.env.*
sudo chmod 600 /opt/docker/aletheia/envs/.env.*