A production Netstamp instance should have one stable HTTPS origin, a private database, persistent secrets, tested backups, and an explicit upgrade process.
Required settings
Set these values in .env before exposing the service:
APP_ENV=production
BACKEND_BASE_URL=https://netstamp.example.com
PUBLIC_WEB_BASE_URL=https://netstamp.example.com
NETSTAMP_VERSION=<tested tag or digest>
DATABASE_PASSWORD=<unique random value>
LOG_PSEUDONYM_KEY=<unique random value>
SYSTEM_SETTINGS_ENCRYPTION_KEY=<unique random value>
AUTH_SESSION_HASH_KEY=<unique random value>
AUTH_API_TOKEN_HASH_KEY=<unique random value>BACKEND_BASE_URL is used for OAuth/OIDC callback URLs, email links, and controller-served probe installer URLs. PUBLIC_WEB_BASE_URL is used for browser-facing links. Both values must be origins only: scheme and host, with no path, query, or fragment.
With APP_ENV=production, session cookies use the __Host- prefix, Secure, HttpOnly, SameSite=Strict, and Path=/. Users must access the site over HTTPS.
Reverse proxy requirements
Terminate TLS in a reverse proxy and forward the complete origin to the container. Preserve these headers:
HostX-Forwarded-ProtoX-Forwarded-ForX-Real-IPwhen your proxy provides itAuthorization
Example Nginx server block:
server {
listen 443 ssl http2;
server_name netstamp.example.com;
ssl_certificate /etc/letsencrypt/live/netstamp.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/netstamp.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Authorization $http_authorization;
}
}Bind the Compose port to loopback when the reverse proxy runs on the same host:
services:
netstamp:
ports:
- "127.0.0.1:3000:8080"If Netstamp must trust client addresses from the proxy, set HTTP_TRUSTED_PROXIES to the proxy’s exact address or CIDR prefixes, separated by commas. Do not trust all addresses unless the container port is otherwise unreachable.
Firewall and network direction
The controller needs:
- inbound HTTPS from browsers, API clients, and probe agents;
- outbound access to configured OAuth/OIDC providers and notification endpoints;
- outbound SMTP when email is enabled;
- database access to PostgreSQL.
Probe agents initiate outbound HTTP(S) connections to the controller. The controller does not need inbound access to probe hosts.
Account bootstrap
The first successfully registered account is granted system administrator access. Create that account before opening registration broadly, then use Admin → System settings to:
- verify backend and public web origins;
- configure SMTP if needed;
- decide whether registration remains enabled;
- decide whether new accounts must verify email;
- add at least one additional system administrator for recovery.
System administrators do not automatically gain access to projects. Project owners must invite them when project access is required.
Production checklist
-
APP_ENV=productionis set. - Every placeholder and development secret was replaced independently.
- The Netstamp and TimescaleDB image versions are pinned and recorded.
- The database port is not exposed publicly.
- HTTPS is valid and HTTP redirects to HTTPS.
-
BACKEND_BASE_URLandPUBLIC_WEB_BASE_URLmatch the public origin. - Trusted proxy ranges are no broader than necessary.
- Registration and email-verification policy are intentional.
- SMTP and every alert notification are tested.
-
/healthzand/api/v1/healthzare monitored. - A database backup was created and restored in a test environment.
- Probe hosts can reach the public controller origin.
- Secrets and
.envare excluded from backups that leave your control, or encrypted before storage.
Verification
curl --fail https://netstamp.example.com/healthz
curl --fail https://netstamp.example.com/api/v1/healthz
curl --fail https://netstamp.example.com/api/v1/openapi.json >/dev/null
curl --fail https://netstamp.example.com/api/v1/install/agent.sh >/dev/nullCreate a disposable probe, confirm its heartbeat, run one check, test one notification, and load a public status page before declaring the deployment ready.