Skip to content

TLS and Reverse Proxy

Rod Christiansen edited this page Oct 8, 2026 · 2 revisions

TLS and Reverse Proxy

This repo ships no reverse proxy and no TLS. There is no proxy service in docker-compose.yml, no certificate handling, and no ACME client. The stack publishes plain HTTP on two host ports and stops there. This page is operator guidance for putting your own front door in front of it.

What the stack exposes

Origin Service Notes
http://<host>:3000 web The dashboard; what people open in a browser
http://<host>:8000 api What agents post to; the dashboard reaches it internally at http://api:8000
— postgres Port not published; reachable only inside the reportmate network

Both published ports bind to all host interfaces. If the host is reachable from anything you do not control, treat the stack as exposed until you have a proxy and a firewall in front of it.

The shape to aim for

Terminate TLS in a proxy on the same host, forward to the two ports on loopback, and give the API and the dashboard distinct public origins — for example https://reportmate.example.com for the dashboard and https://api.reportmate.example.com for the API. Caddy, nginx, Traefik, or a cloud load balancer all work; the repo takes no position.

Then reflect those origins back into the stack:

PUBLIC_URL=https://reportmate.example.com
PUBLIC_API_URL=https://api.reportmate.example.com

PUBLIC_URL becomes the API's CORS_ORIGINS. PUBLIC_API_URL becomes the dashboard's NEXT_PUBLIC_API_BASE_URL, which the dashboard reads only as a fallback. Neither affects how the dashboard reaches the API: the browser calls the dashboard's own routes, and those call API_BASE_URL, fixed to http://api:8000 inside the Compose network. The API's public name matters to agents, not to the dashboard.

Stop publishing to the world

Once a proxy is in front, edit the port mappings in docker-compose.yml so the containers only listen on loopback and the proxy is the sole path in:

    ports:
      - "127.0.0.1:3000:3000"

Do the same for 8000:8000 on api. This is a local edit to the Compose file; there is no variable for it.

If you enable real sign-in

NEXTAUTH_URL must be the dashboard's public HTTPS URL, and it must match the redirect URI registered with your identity provider. NextAuth builds callback URLs from it, so a value left at http://localhost:3000 behind an HTTPS proxy produces callbacks that fail. NEXTAUTH_URL is not in .env.example — add it to the web service yourself, as described in Configuration.

Your proxy should also forward the usual X-Forwarded-Proto and X-Forwarded-Host headers so the application sees the scheme and host the browser used.

The client side

Agents need to reach the API over whatever name you published. Point them at https://api.reportmate.example.com and give them the REPORTMATE_PASSPHRASE from .env. Once TLS is in place there is no reason to leave port 8000 open on the host at all.

What is not verified here

The specifics above — header names, proxy configuration, certificate issuance — are standard reverse-proxy practice, not behaviour implemented in this repo. The only claims grounded in the repo itself are the published ports, the two public-origin variables, and the fixed internal API_BASE_URL.

Clone this wiki locally