Aller au contenu

Nginx Configuration Pattern

Three-file convention

Every site managed by Aether uses three nginx config files:

File Purpose Managed by
<site>.conf.full Production config (HTTPS, proxy/static, headers) Git (aether repo)
<site>.conf.temp Maintenance mode (HTTP only, returns 503, allows certbot) Git (aether repo)
<site>.conf Active config — symlink-like copy of either .full or .temp Operator (manual or *-init)
nginx/conf.d/
├── aletheia-prod.conf.full    ← git-tracked template (HTTPS)
├── aletheia-prod.conf.temp    ← git-tracked template (maintenance)
├── aletheia-prod.conf         ← ACTIVE (copy of .full or .temp, NOT in git)
├── monitoring.conf.full
├── monitoring.conf.temp
├── monitoring.conf            ← ACTIVE
├── docs.conf.full
├── docs.conf.temp
└── docs.conf                  ← ACTIVE

Why the active .conf is not in git

The active config is a deliberate operator choice:

  • During initial setup, sites start in .temp mode (HTTP only) so certbot can obtain SSL certs
  • After cert acquisition, the operator switches to .full (HTTPS)
  • For maintenance windows, the operator switches back to .temp
  • make deploy intentionally does NOT overwrite the active .conf — it only updates the templates

If make deploy overwrote active configs, it could: - Break a site that's intentionally in maintenance mode - Activate HTTPS before SSL certs exist - Disrupt a controlled rollout

Lifecycle

1. First-time setup (new service)

Each service has a make *-init target that handles the full bootstrap:

# Pattern used by umami-init, helios-init, docs-init:
cp .conf.temp  .conf          # Start in maintenance mode (HTTP)
restart nginx                   # Apply config
certbot obtain cert             # Get SSL certificate
cp .conf.full  .conf          # Switch to production (HTTPS)
reload nginx                    # Apply without downtime

2. Fresh server (setup.sh)

setup.sh does this for ALL sites at once: - Step 10: copies all .conf.temp.conf (maintenance mode) - Step 15: starts nginx - Step 16: obtains SSL certs for all domains - Step 16: copies all .conf.full.conf (production mode)

3. Day-to-day config changes

# Edit the template in the repo
vim nginx/conf.d/aletheia-prod.conf.full

# Deploy templates to server (does NOT touch active .conf)
make deploy

# If the change affects the active config, manually activate:
sudo cp /opt/docker/nginx/conf.d/aletheia-prod.conf.full \
        /opt/docker/nginx/conf.d/aletheia-prod.conf
docker exec nginx-proxy nginx -t && docker exec nginx-proxy nginx -s reload

4. Maintenance mode

# Switch to maintenance (returns 503 to all requests)
sudo cp /opt/docker/nginx/conf.d/aletheia-prod.conf.temp \
        /opt/docker/nginx/conf.d/aletheia-prod.conf
docker exec nginx-proxy nginx -s reload

# ... do maintenance ...

# Switch back to production
sudo cp /opt/docker/nginx/conf.d/aletheia-prod.conf.full \
        /opt/docker/nginx/conf.d/aletheia-prod.conf
docker exec nginx-proxy nginx -s reload

Current sites

Site Domain Config prefix
Aletheia prod aletheia.groupe-suffren.com aletheia-prod
Aletheia staging aletheia-staging.groupe-suffren.com aletheia-staging
Aletheia dev aletheia-dev.groupe-suffren.com aletheia-dev
Helios prod cabinet-dentaire-aubagne.fr, etc. helios-prod
Helios staging cda-staging.groupe-suffren.com, etc. helios-staging
Helios dev cda-dev.groupe-suffren.com, etc. helios-dev
Monitoring monitoring.groupe-suffren.com monitoring
Analytics analytics.groupe-suffren.com analytics
Documentation docs.groupe-suffren.com docs

Volume mounts

Nginx runs in a Docker container (nginx-proxy). It can only serve files that are mounted as volumes in nginx/docker-compose.yml:

volumes:
  - ./conf.d:/etc/nginx/conf.d:ro           # configs
  - aletheia-prod-static:/data/aletheia/...  # app static files
  - /opt/docker/mnemosyne/site:/data/docs:ro # docs site

If you add a new static site, you must: 1. Add the volume mount to docker-compose.yml 2. Run make deploy to copy the compose file 3. Recreate nginx: make restart-nginx (reload is not enough for new volumes)