Domains and automatic HTTPS
Serve Workforce Intelligence on your own domain with a certificate that Caddy obtains and renews for you.
The web container runs Caddy. Without a domain it serves plain HTTP on port 80. When you give
it a domain, Caddy's automatic HTTPS takes over: it obtains a real Let's Encrypt certificate,
listens on port 443, redirects HTTP to HTTPS, and renews the certificate on its own. There is
nothing else to configure.
Set up a domain#
-
Point a DNS record for your domain at the box's public address. On AWS you can have the CloudFormation template create the Route 53 record with the
DomainNameandHostedZoneIdparameters. That requiresAllocateElasticIp=true, because a record pointing at an ephemeral IP would break on every stop and start. See Install on AWS with CloudFormation. -
Make sure ports 80 and 443 are reachable from the public internet. The certificate authority verifies the domain over them, and a box that is only reachable through NAT cannot complete verification.
-
Edit
.env(/opt/wi/.envon AWS) and set these keys. Each must appear once, so edit an existing line rather than adding a second one.WI_DOMAIN=wi.example.com WI_ALLOWED_ORIGIN=https://wi.example.com WI_DOKKU_SSH_HOST=wi.example.comWI_API_BASE_URLandWI_PUBLIC_BASE_URLfollowWI_ALLOWED_ORIGINautomatically. -
Apply it:
cd /opt/wi sudo docker compose -f docker-compose.prod.yml up -dOn a first install, skip this step.
install.shstarts everything.
WI_DOMAIN is the bare domain name. WI_ALLOWED_ORIGIN is the full origin, with https://.
If WI_DOMAIN is blank or unset, the web container serves plain HTTP on port 80.
Where the certificate is kept#
Caddy keeps its certificates and its account with the certificate authority in the
wi-prod-caddy-data Docker volume. Only the very first start of web runs the issuance. Later
recreations, such as docker compose up -d or an in-app update, reuse the stored certificate.
Never delete the wi-prod-caddy-data volume. Let's Encrypt limits repeat issuance for the
same domain, so deleting it can leave you unable to get a new certificate for a while.
Domains on the .dev top-level domain#
Chrome has the entire .dev top-level domain on its HSTS preload list. Chrome refuses plain
HTTP for any .dev domain, so HTTPS has to work before the site is usable in that browser.
Testing with curl over http:// can appear to work while the real browser does not.
Custom ports#
If you change WI_HTTP_PORT or WI_HTTPS_PORT, put the port in WI_ALLOWED_ORIGIN. Automatic
certificate issuance still needs the certificate authority to reach the standard ports 80 or
443 on your domain.
What Caddy routes#
On the one origin, the web container serves the web app and forwards /api/*, /auth/*, and
/healthz to the application. Deployed Apps are served under /apps/serve/<app id>/ on the
same origin, so they need no separate hostname or wildcard certificate.