HTTPS and certificates
Plugboard handles student records, staff credentials and password resets. It should not be served over plain HTTP to anything except localhost during a first look.
Start it with no certificate and it serves plain HTTP and says so. Silence would be worse.
First, set the address
Section titled “First, set the address”Whatever route you take, set the address people actually type:
PUBLIC_URL=https://helpdesk.yourschool.orgPUBLIC_HOST=helpdesk.yourschool.orgThis is not cosmetic. It is the base for every link the product emails, the single sign-on return address, and the list of addresses the browser is allowed to talk to. Set it to an internal name and you will send tracking links your families cannot open.
https://x, https://x/ and http://x count as three different values, so
copy it exactly.
Pick a route
Section titled “Pick a route”In order of how little work they are.
| Your situation | Do this |
|---|---|
| Publicly reachable, ports 80 and 443 open | Use the bundled Caddy option. It gets a free certificate and renews it, with nothing further to do |
| School network you do not control, no inbound ports | Use the bundled Cloudflare Tunnel option. Nothing is opened; it dials out |
| You already have a wildcard certificate | Point Plugboard at the file |
| Your school runs its own certificate authority | Point Plugboard at the file |
| You already run nginx, IIS or similar | Keep using it, and send traffic to Plugboard |
The bundled options
Section titled “The bundled options”One command each, on the Docker stack:
# Free certificate, renewed automaticallydocker compose --env-file .env -f docker-compose.prod.yml --profile caddy up -d# No inbound ports at alldocker compose --env-file .env -f docker-compose.prod.yml --profile tunnel up -dThe tunnel is the one to reach for on a school network where opening a port
means a change request. Set TUNNEL_TOKEN first.
Your own certificate
Section titled “Your own certificate”Point Plugboard at the files and restart. Both forms are read from disk at startup, so renewing means replacing the file and restarting.
A PKCS#12 file, which is what Active Directory Certificate Services and most Windows tooling produce:
TLS_PFX_FILE=C:\certs\helpdesk.pfxTLS_PFX_PASSWORD=...Or PEM, from an internal authority or a purchased wildcard:
TLS_CERT_FILE=/etc/ssl/certs/helpdesk.crtTLS_KEY_FILE=/etc/ssl/private/helpdesk.keyTLS_CA_FILE=/etc/ssl/certs/chain.crtInclude the chain file if your issuer gives you one. Without it a site usually works in a desktop browser and fails on Android and on phones, which is a confusing thing to be debugging six months later when nobody remembers the install.
TLS 1.2 is the floor, HTTP redirects to HTTPS, and the strict-transport header is sent.
Your existing reverse proxy
Section titled “Your existing reverse proxy”If your school already runs nginx, IIS or an appliance, keep using it. Start Plugboard with no ingress option so it listens internally, then send it traffic:
/api/to the API on port 4000- everything else to the web app on port 3000
One setting matters. The path /api/events/ carries the desk’s live
updates. Your proxy must pass it through without buffering, or updates
arrive in bursts every thirty seconds instead of immediately and the product
looks broken. In nginx that is proxy_buffering off; for that location, with a
long read timeout. In IIS, turn off response buffering for that path in the
Application Request Routing settings.
Plugboard trusts the standard forwarded-protocol headers, so it knows it is behind HTTPS.
A free certificate on a school network
Section titled “A free certificate on a school network”The usual free-certificate check needs port 80 reachable from the internet, which a lot of school networks will not allow. Two ways round it:
- Cloudflare Tunnel, which needs no inbound ports at all.
- A DNS-based check, which proves you control the domain with a DNS record instead. Caddy supports this with the module for your DNS provider.
Internal-only deployments
Section titled “Internal-only deployments”If the desk should not be reachable from outside the school, point the name at a private address inside and at nothing outside. Use your own certificate authority, or the DNS-based check, since the port 80 method needs to be publicly reachable.
You will also want ALLOW_PRIVATE_EGRESS=1 so service monitors can check
addresses on your own network. Plugboard blocks those by default so a monitor
cannot be pointed somewhere it should not go.
Checklist
Section titled “Checklist”-
PUBLIC_URLset to the address people type, withhttps:// - Certificate in place, including the chain file if you were given one
- HTTP redirects to HTTPS
-
/api/events/not buffered, if you run your own proxy - Renewal handled. The bundled options renew themselves; your own certificate needs a diary entry
- Tested from a machine that is not the server, and from a phone
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause |
|---|---|
| Browser warns about the certificate | Self-signed, or the chain is missing |
| Works on a desktop, fails on Android | Missing chain. Same fix |
| The console loads but never updates | A proxy is buffering /api/events/ |
| Errors in the browser about blocked requests | PUBLIC_URL does not match the address bar exactly |
| Emails link to the wrong address | PUBLIC_URL still points at the old one. Restart after changing it |
| “HTTPS not started” in the log | Wrong certificate path, or wrong PFX password. The log names the file it tried |
| Certificate never issues | Port 80 is not reachable. Use the tunnel or a DNS-based check |