Skip to main content

HTTPS

All traffic goes through Traefik (pch_traefik, ports 80 and 443), which terminates TLS and routes to the containers. No certificate is managed by hand.

Certificates​

  • Issued by Let's Encrypt (HTTP challenge on port 80), requested automatically for every name declared in the containers' Traefik labels.
  • Renewed automatically by Traefik; stored in the traefik_letsencrypt volume (acme.json).
  • Port 80 redirects to 443 for every name.

To add a host name: create the DNS record first, then add the Host(...) rule to the relevant container's labels and recreate it. If Traefik tried before the DNS existed, it serves its "TRAEFIK DEFAULT CERT": docker restart pch_traefik retries the request.

note

The contact address registered with Let's Encrypt (acme.email option in the compose file) is the current technical lead's; replace it with a UCP-PCH address at handover.

Served names​

ServerNameTo
Productionbemba.ucp-pch.org, ucp-pch.orgapplication (/api, /photos → backend)
Productionmariacare.ucp-pch.org, sig.ucp-pch.orgredirect to bemba.ucp-pch.org
Productiondocubemba.ucp-pch.orgdocumentation
Pre-productionsig-preprod.ucp-pch.orgapplication
Pre-productionkf/kc/ee.kobo.ucp-pch.orgKoboToolbox (Traefik → Kobo's nginx)
Pre-productiongitlab.ucp-pch.orgGitLab

Security headers​

Set by the frontend Nginx (nginx/frontend.conf):

HeaderValue
Strict-Transport-Securityone year, subdomains included
Content-Security-Policydefault-src 'self', scripts from the domain only, connect-src limited to the domain, KoboToolbox and Sentry
X-Frame-OptionsSAMEORIGIN
X-Content-Type-Optionsnosniff
Referrer-Policystrict-origin-when-cross-origin

Nginx and PHP versions are not advertised (server_tokens off, expose_php Off).

Check​

curl -sI https://bemba.ucp-pch.org/ | grep -iE "strict-transport|content-security|x-frame"
curl -sv https://bemba.ucp-pch.org/ -o /dev/null 2>&1 | grep -E "issuer|expire date"

External test: SSL Labs (https://www.ssllabs.com/ssltest/).

Mixed content​

The application is served over HTTPS only and calls the API through a relative path (/api): no plain-HTTP call is possible from the browser. A third-party http:// service would be blocked by the CSP anyway.