First sign-in and HTTPS
What to do in the first five minutes, then HTTPS. There is no TLS setting to turn on: put a certificate in the tls folder and Trinium serves it.
Open http://<your-server>:8080 (the TRINIUM_HTTP_PORT you set) and sign in as admin / admin.
Then, in this order:
- Change the
adminpassword, under your profile in the top right. This is the super admin account and the one that can never be locked out of this instance, so it is also the first credential anyone will try. Do this before the server is reachable from anywhere you do not control. - Back up your master key. Trinium shows a reminder across the top until you confirm it; the reminder tells you where the file is and how to read it. See Configure for what it protects.
- Create real user accounts under Users, and give yourself one that is not
admin. - Add your data sources under Connections.
- Build a pipeline and run it.
Turning on HTTPS
There is no setting. Put your certificate and its key in the tls folder beside compose.yaml, and Trinium serves HTTPS.
cd ~/trinium sudo mkdir -p tls sudo cp /path/to/your-certificate.pem tls/cert.pem sudo cp /path/to/your-private-key.pem tls/key.pem sudo chown -R 10001:10001 tls && sudo chmod 700 tls && sudo chmod 600 tls/key.pem
The key must be readable by uid 10001, the user Trinium runs as, and by nobody else, which is what the last line does. A key Trinium cannot read is a refusal to start that names this fix, never a quiet fall back to plain HTTP.
| File | What goes in it |
|---|---|
tls/cert.pem | Your certificate, PEM encoded. If your CA gave you a chain, concatenate it into this one file: your certificate first, then each issuer above it. |
tls/key.pem | The matching private key, PEM encoded. PKCS#8, PKCS#1 and SEC1 are all accepted. It must not be passphrase-protected. |
Then set the port to 443 in .env and restart:
# .env TRINIUM_HTTP_PORT=443
docker compose up -d
Check the banner in docker compose logs. It names the transport, every time:
๐ Server running on port 443 โ HTTPS (/trinium/tls/cert.pem) ๐ Server running on port 8080 โ HTTP (no certificate in /trinium/tls)
Renewal needs no restart. Replace tls/cert.pem and tls/key.pem with the same two sudo cp lines, then run the chown/chmod line again; Trinium picks the new pair up within a minute, on the next connection. Nothing is dropped. If the new pair cannot be loaded it keeps serving the old certificate and says so in the log, so a half-finished renewal is never an outage.
One file without the other stops the boot. Trinium will not fall back to plain HTTP on its own: an operator who set up a certificate must never be silently unencrypted. The log names the file that is missing.
Leaving tls/ empty is fine and fully supported: Trinium serves plain HTTP, exactly as before.
Once Trinium serves HTTPS, browsers remember it for a year. Every HTTPS response carries Strict-Transport-Security, which tells a browser to refuse plain HTTP to this host name. If you later empty tls/ and go back to HTTP on the same name, browsers that have visited will not connect until the year is up. Moving TLS to a proxy in front keeps HTTPS, so that is unaffected.
Already have a reverse proxy?
Keep using it. Leave tls/ empty and terminate TLS at your nginx, Caddy, load balancer or ingress controller as you do today. Trinium needs no special configuration behind one: it sets no cookies and reads no forwarded headers. It still sends its other browser security headers; only Strict-Transport-Security is your proxy's to send, as below.
server {
listen 443 ssl;
server_name trinium.example.com;
ssl_certificate /etc/ssl/certs/trinium.pem;
ssl_certificate_key /etc/ssl/private/trinium.key;
# Trinium accepts file uploads up to 2 GB; nginx defaults to 1 MB.
client_max_body_size 2g;
# A large pipeline run can take a while to respond.
proxy_read_timeout 300s;
# Tell browsers to use HTTPS only for this host. Trinium sends this itself only when it
# serves HTTPS; behind a proxy, the proxy says it.
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}No certificate yet?
For evaluation you can make one on the server. Do this on the host, not inside the container, because the Trinium image has no openssl (and no shell):
cd ~/trinium openssl req -x509 -newkey rsa:2048 -nodes -days 365 \ -keyout key.pem -out cert.pem \ -subj "/CN=trinium.example.com" \ -addext "subjectAltName=DNS:trinium.example.com" sudo mkdir -p tls && sudo cp cert.pem tls/cert.pem && sudo cp key.pem tls/key.pem sudo chown -R 10001:10001 tls && sudo chmod 700 tls && sudo chmod 600 tls/key.pem rm cert.pem key.pem
Browsers will warn that a self-signed certificate is not trusted. That is expected, and it is why Trinium does not generate one for you. Get a real certificate before anyone else uses the instance; your own internal CA is fine.
Why this matters beyond encryption
Two things simply do not work over plain HTTP, and neither is Trinium's choice:
- Single sign-on. Entra ID, Okta and every other identity provider refuse a non-HTTPS redirect URI. You cannot finish OIDC setup without TLS.
- Copy buttons, and anything using browser cryptography. Browsers gate those APIs behind a secure connection, so on plain HTTP they are switched off and Trinium says so instead of failing silently.
Letting other systems call the Run API
The Run API (/api/v1/) answers on the same address and port as the app, with the same certificate. Two things to know before another system calls it:
- AWS Step Functions and Amazon EventBridge call only a public DNS name with a publicly trusted certificate, even when they reach Trinium inside your own network. A certificate from your internal CA works for browsers and fails for them. Give Trinium a certificate from a public authority (or put a load balancer holding one in front of it).
- To expose the API without exposing the app, forward only paths starting with
/api/v1/to Trinium at your load balancer, and limit which addresses may call it there.
Tokens are made in Settings โ API. Send them over HTTPS only: a token sent over plain HTTP can be read on the way.