Guide
HTTPS and reverse proxies
Serve Heimnull's web interface over HTTPS, either behind a reverse proxy such as Caddy or nginx, or from its own bundled web server.
Heimnull serves its web interface and API over plain HTTP on HN_HTTP_PORT (80). Every page except the login form needs a login, but passwords and session cookies cross the network in the clear. Anywhere beyond a trusted management network, add HTTPS.
There are two ways:
- A reverse proxy in front of Heimnull handles TLS. We recommend this, especially with Caddy, which gets and renews certificates by itself.
- The bundled web server serves HTTPS itself, with a certificate you provide.
Either way, session cookies get the Secure flag automatically once requests arrive over HTTPS.
Reverse proxy on the same server
Section titled “Reverse proxy on the same server”Move Heimnull off port 80 so the proxy can take 80 and 443. In /opt/heimnull/.env:
HN_HTTP_PORT=8088Any free port works except those Heimnull already uses on the host’s loopback: 8080 (its internal API), 5432, 8123, 9000 and 50051. See Ports.
Apply it:
cd /opt/heimnullsudo docker compose up -d --waitThen point the proxy at 127.0.0.1:8088. With Caddy, installed on the host from its Debian packages:
heimnull.example.com { reverse_proxy 127.0.0.1:8088}A proxy that connects from 127.0.0.1 is trusted automatically: Heimnull takes the browser’s address from its X-Forwarded-For header and sees X-Forwarded-Proto: https.
Reverse proxy on another machine
Section titled “Reverse proxy on another machine”Point the proxy at the Heimnull server’s address and port, and tell Heimnull to trust it. In .env, with the proxy at 192.0.2.10:
HN_HTTP_TRUSTED_PROXIES=192.0.2.10The value is a comma-separated list of addresses or CIDRs. Apply it with sudo docker compose up -d --wait.
Heimnull then takes the browser’s address from the proxy’s X-Forwarded-For, so login throttling and the audit log see real clients, and it marks the session cookie Secure from X-Forwarded-Proto: https. Forwarding headers from anyone else are ignored.
If a proxy sends forwarding headers without being trusted, the System page names its address and the line to add to .env.
What the proxy must do
Section titled “What the proxy must do”- Keep the
Hostheader. Caddy and most proxies do by default. Heimnull refuses state-changing requests whoseOriginnames another host. - Pass WebSockets. The Live page streams over a WebSocket at
/ws/live. Caddy does this by default; nginx needs theUpgradeheaders below. - Send
X-Forwarded-ForandX-Forwarded-Proto.
An nginx site, for example:
server { listen 443 ssl; server_name heimnull.example.com; ssl_certificate /etc/ssl/heimnull/fullchain.pem; ssl_certificate_key /etc/ssl/heimnull/privkey.pem;
location / { proxy_pass http://127.0.0.1:8088; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 1h; }}Lock it down
Section titled “Lock it down”- Firewall
HN_HTTP_PORTto the proxy only, so nobody can go around it. - Create the admin account before you publish the address. Until the first admin exists, anyone who reaches the page can create it.
- Optionally add
Strict-Transport-Securityat the proxy. - Set Settings → Notifications → Base URL to the HTTPS address, so links in alerts use it.
HTTPS from the bundled web server
Section titled “HTTPS from the bundled web server”Heimnull’s container runs Caddy as its web server. To have it serve HTTPS with your certificate, give it your own Caddyfile through a docker-compose.override.yml next to docker-compose.yml. Compose reads the override file automatically, and an upgrade’s new docker-compose.yml leaves it alone.
-
Copy the image’s Caddyfile as a starting point:
cd /opt/heimnullsudo sh -c 'docker run --rm --entrypoint cat registry.heimnull.com/heimnull:latest /etc/caddy/Caddyfile > Caddyfile' -
Edit it: replace the site address
:{$HN_HTTP_PORT:80}with your host name, removeauto_https off, and add your certificate inside the site block:tls /certs/cert.pem /certs/key.pemOr use
tls internalfor a certificate from Caddy’s own CA. -
Put the certificate and key in
/opt/heimnull/certs/, readable by uid 10001 (the web server’s user). -
Create
/opt/heimnull/docker-compose.override.yml:services:heimnull:environment:HN_WEB_DATA: /var/lib/heimnull/webvolumes:- ./Caddyfile:/etc/caddy/Caddyfile:ro- ./certs:/certs:ro- hn-web:/var/lib/heimnull/webvolumes:hn-web: {} -
Apply it, and open port 443 in the firewall:
sudo docker compose up -d --wait
Keep your Caddyfile in step with the image’s when you upgrade: compare it with the new image’s copy after each release, since a release can change what the web server does.