# Enabling HTTPS with Certbot and Nginx The production Docker stack ships with an Nginx front-end (the `frontend` service). Follow these steps to terminate HTTPS traffic with Let's Encrypt certificates. ## 1. Prerequisites - DNS `A` records for your domain (e.g. `vip.example.com`) pointing to `162.243.171.221`. - Ports **80** and **443** open in the DigitalOcean firewall. - Docker Compose production stack deployed. - Certbot installed on the droplet (`apt-get install -y certbot` already run). ## 2. Obtain certificates Run Certbot in standalone mode (temporarily stop the `frontend` container during issuance if it is already binding to port 80): ```bash # Stop the frontend container temporarily docker compose -f docker-compose.prod.yml stop frontend # Request the certificate (replace the domain names) sudo certbot certonly --standalone \ -d vip.example.com \ -d www.vip.example.com # Restart the frontend container docker compose -f docker-compose.prod.yml start frontend ``` Certificates will be stored under `/etc/letsencrypt/live/vip.example.com/`. ## 3. Mount certificates into the frontend container Copy the key pair into the repository (or mount the original directory as a read-only volume). For example: ```bash sudo mkdir -p /opt/vip-coordinator/certs sudo cp /etc/letsencrypt/live/vip.example.com/fullchain.pem /opt/vip-coordinator/certs/ sudo cp /etc/letsencrypt/live/vip.example.com/privkey.pem /opt/vip-coordinator/certs/ sudo chown root:root /opt/vip-coordinator/certs/*.pem sudo chmod 600 /opt/vip-coordinator/certs/privkey.pem ``` Update `docker-compose.prod.yml` to mount the certificate directory (uncomment the example below): ```yaml frontend: volumes: - /opt/vip-coordinator/certs:/etc/nginx/certs:ro ``` ## 4. Enable the TLS server block Edit `frontend/nginx.conf`: 1. Uncomment the TLS server block and point to `/etc/nginx/certs/fullchain.pem` and `privkey.pem`. 2. Change the port 80 server block to redirect to HTTPS (e.g. `return 301 https://$host$request_uri;`). Example TLS block: ```nginx server { listen 443 ssl http2; server_name vip.example.com www.vip.example.com; ssl_certificate /etc/nginx/certs/fullchain.pem; ssl_certificate_key /etc/nginx/certs/privkey.pem; include /etc/nginx/snippets/ssl-params.conf; # optional hardening proxy_cache_bypass $http_upgrade; ... } ``` Rebuild and redeploy the frontend container: ```bash docker compose -f docker-compose.prod.yml build frontend docker compose -f docker-compose.prod.yml up -d frontend ``` ## 5. Automate renewals Certbot installs a systemd timer that runs `certbot renew` twice a day. After renewal, copy the updated certificates into `/opt/vip-coordinator/certs/` and reload the frontend container: ```bash sudo certbot renew --dry-run sudo cp /etc/letsencrypt/live/vip.example.com/{fullchain.pem,privkey.pem} /opt/vip-coordinator/certs/ docker compose -f docker-compose.prod.yml exec frontend nginx -s reload ``` Consider scripting the copy + reload to run after each renewal (e.g. with a cron job). ## 6. Hardening checklist - Add `ssl_ciphers`, `ssl_prefer_server_ciphers`, and HSTS headers to Nginx. - Restrict `ADMIN_PASSWORD` to a strong value and rotate `JWT_SECRET`. - Enable a firewall (DigitalOcean VPC or `ufw`) allowing only SSH, HTTP, HTTPS. - Configure automatic backups for PostgreSQL (snapshot or `pg_dump`).