Skip to content

SSL Certificates

All public-facing SSERIS services are served over HTTPS. SSL termination happens at the Nginx reverse proxy (dev_nginx, a global-mode service in the DEV stack) which handles TLS for all domains.

PropertyValue
Termination pointdev_nginx (global mode, runs on both nodes)
Certificate typeLet’s Encrypt (free, auto-renewable)
Domains coveredAll *.ayinza.dev subdomains
RenewalNeeds manual renewal or certbot cron
  1. Clients connect to *.ayinza.dev over HTTPS (port 443)
  2. DNS points to Contabo’s public IP (84.247.134.135)
  3. Nginx on Contabo terminates SSL and proxies to backend services
  4. Backend services receive plain HTTP traffic internally
Terminal window
# Check expiry for any domain
echo | openssl s_client -connect ayinza.dev:443 2>/dev/null | openssl x509 -noout -dates
# Check which certificate is being served
echo | openssl s_client -connect auth.ayinza.dev:443 2>/dev/null | openssl x509 -noout -subject -issuer
# Check certificate from inside the server
certbot certificates
Terminal window
# Dry run (test without actually renewing)
certbot renew --dry-run
# Actual renewal
certbot renew
# Force renewal for a specific domain
certbot certonly --force-renewal -d ayinza.dev -d "*.ayinza.dev"

After renewing certificates, Nginx needs to pick up the new certs:

Terminal window
# Reload Nginx to use new certificates
docker service update --force dev_nginx

When you add a new subdomain:

  1. Add the DNS record pointing to Contabo (84.247.134.135)
  2. If using a wildcard cert (*.ayinza.dev), no new cert is needed
  3. If the domain is outside the wildcard, generate a new cert:
    Terminal window
    certbot certonly -d newdomain.example.com
  4. Update the Nginx config to include the new server block with SSL
  5. Redeploy Nginx
Terminal window
# Let's Encrypt certificates (standard location)
/etc/letsencrypt/live/ayinza.dev/fullchain.pem # Certificate + chain
/etc/letsencrypt/live/ayinza.dev/privkey.pem # Private key
# Check all managed certificates
ls -la /etc/letsencrypt/live/

Browsers will show a security warning. Renew immediately:

Terminal window
certbot renew
docker service update --force dev_nginx
  • Check that the full chain is being served (not just the leaf certificate)
  • Verify the certificate matches the domain being accessed
  • Check that the Nginx config references fullchain.pem, not just cert.pem
Terminal window
# Check certbot logs
cat /var/log/letsencrypt/letsencrypt.log
# Common issues:
# - Port 80 not accessible (needed for HTTP-01 challenge)
# - DNS not pointing to this server (needed for DNS-01 challenge)
# - Rate limit exceeded (Let's Encrypt limits ~50 certs per week per domain)