How to Configure SSL/TLS for Uptime Kuma: Native HTTPS and Reverse Proxy Methods
Uptime Kuma can serve its web interface over HTTPS either natively by reading TLS certificates from command-line arguments or environment variables, or by sitting behind a reverse proxy that handles TLS termination.
Uptime Kuma, the popular open-source monitoring tool by louislam/uptime-kuma, provides built-in support for secure connections without requiring external patches. You can configure SSL/TLS for Uptime Kuma directly through its Node.js server configuration or delegate encryption to an external reverse proxy, with both methods fully supported in server/config.js and server/uptime-kuma-server.js.
Native HTTPS Configuration
Uptime Kuma's server automatically enables HTTPS when it detects both a private key and certificate. In server/config.js, the application checks for --ssl-key and --ssl-cert arguments (or corresponding environment variables) and sets isSSL to true only when both files are specified and readable.
Method 1: Command-Line Flags
Start the server with the following flags to enable direct HTTPS:
node server/server.js \
--ssl-key /path/to/privkey.pem \
--ssl-cert /path/to/fullchain.pem \
--ssl-key-passphrase "optional-passphrase"
The parseArgs utility in src/util.ts processes these flags, making them available to the configuration loader.
Method 2: Environment Variables
For Docker containers or systemd services, use environment variables:
export UPTIME_KUMA_SSL_KEY=/path/to/privkey.pem
export UPTIME_KUMA_SSL_CERT=/path/to/fullchain.pem
export UPTIME_KUMA_SSL_KEY_PASSPHRASE="optional-passphrase"
node server/server.js
Alternatively, the generic aliases SSL_KEY and SSL_CERT are also accepted. The extra/healthcheck.js script respects these same variables when performing health checks against HTTPS endpoints.
How the Server Handles TLS
The configuration logic in server/config.js exports an isSSL boolean that determines the server type:
// server/config.js – TLS configuration logic
const args = require('minimist')(process.argv.slice(2));
const sslKey = args["ssl-key"] || process.env.UPTIME_KUMA_SSL_KEY || process.env.SSL_KEY;
const sslCert = args["ssl-cert"] || process.env.UPTIME_KUMA_SSL_CERT || process.env.SSL_CERT;
const sslKeyPassphrase = args["ssl-key-passphrase"] ||
process.env.UPTIME_KUMA_SSL_KEY_PASSPHRASE ||
process.env.SSL_KEY_PASSPHRASE;
const isSSL = Boolean(sslKey && sslCert);
In server/uptime-kuma-server.js, the application creates an HTTPS server when isSSL is true:
// server/uptime-kuma-server.js – Server creation
const { isSSL, sslKey, sslCert, sslKeyPassphrase } = require("./config");
let httpServer;
if (isSSL) {
const https = require("https");
const fs = require("fs");
httpServer = https.createServer({
key: fs.readFileSync(sslKey),
cert: fs.readFileSync(sslCert),
passphrase: sslKeyPassphrase,
}, app);
console.log("🔐 HTTPS enabled");
} else {
const http = require("http");
httpServer = http.createServer(app);
}
httpServer.listen(port);
If either the key or certificate is missing, the server falls back to HTTP on port 3001.
Reverse Proxy SSL/TLS Configuration (Recommended)
For production environments, terminating TLS at a reverse proxy is the preferred architecture. This approach centralizes certificate management with tools like Let's Encrypt, offloads cryptographic processing from the Node.js process, and simplifies firewall rules by using HTTP internally.
NGINX Configuration Example
server {
listen 443 ssl http2;
server_name monitor.example.com;
ssl_certificate /etc/letsencrypt/live/monitor.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/monitor.example.com/privkey.pem;
location / {
proxy_pass http://localhost:3001;
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;
}
}
After reloading NGINX, access https://monitor.example.com. The Uptime Kuma interface automatically detects the reverse proxy via the X-Forwarded-Proto header and displays a secure lock icon.
Built-in Reverse Proxy Help
The web interface includes a dedicated reverse proxy help panel in src/components/settings/ReverseProxy.vue and a footer link in src/layouts/Layout.vue that direct users to the official wiki guides for Cloudflare Tunnel and other proxy configurations.
Troubleshooting Common SSL/TLS Issues
| Symptom | Likely Cause | Solution |
|---|---|---|
| Server starts but UI remains HTTP | isSSL is false due to missing or unreadable key/cert |
Verify absolute file paths and permissions; check logs for "SSL key missing" messages |
| Browser shows certificate warnings | Using self-signed certificates without proper trust store | Use Let's Encrypt or add the certificate to the client's trust store |
| 502 Bad Gateway from proxy | Kuma not listening on expected port or proxy misconfiguration | Confirm Uptime Kuma runs on port 3001 and the proxy_pass URL matches |
| "Invalid passphrase" error | Passphrase does not match the encrypted private key | Omit --ssl-key-passphrase for unencrypted keys or provide the correct password |
Summary
- Native HTTPS: Supply
--ssl-keyand--ssl-certflags (orUPTIME_KUMA_SSL_KEY/UPTIME_KUMA_SSL_CERTenvironment variables) to enable direct TLS termination in the Node.js server. - Reverse Proxy: Terminate SSL/TLS externally using NGINX, Caddy, or Cloudflare Tunnel, then forward plain HTTP to Uptime Kuma's internal port.
- Configuration Source: The
server/config.jsfile handles all TLS option parsing and exportsisSSL,sslKey,sslCert, andsslKeyPassphrasetoserver/uptime-kuma-server.js. - Health Checks: The
extra/healthcheck.jsutility respects the same SSL environment variables when checking HTTPS endpoints. - Security Best Practice: For production deployments, use a reverse proxy to handle certificate rotation and TLS offloading.
Frequently Asked Questions
How do I enable HTTPS without using a reverse proxy?
Provide the absolute paths to your PEM-encoded private key and full-chain certificate using either the --ssl-key and --ssl-cert command-line flags or the UPTIME_KUMA_SSL_KEY and UPTIME_KUMA_SSL_CERT environment variables. The server automatically creates an HTTPS listener when both files are present and readable.
Can I use a passphrase-protected private key with Uptime Kuma?
Yes. Specify the passphrase using the --ssl-key-passphrase flag or the UPTIME_KUMA_SSL_KEY_PASSPHRASE environment variable. The passphrase is passed directly to the Node.js https.createServer() options object in server/uptime-kuma-server.js.
Why does Uptime Kuma still start on HTTP after I configured SSL?
The server evaluates isSSL = Boolean(sslKey && sslCert) in server/config.js. If either variable is undefined, empty, or points to a non-existent file, the server falls back to HTTP. Verify that both paths are absolute, the files exist, and the process has read permissions.
Does the health check endpoint work with HTTPS enabled?
Yes. The extra/healthcheck.js script reads the same UPTIME_KUMA_SSL_KEY, UPTIME_KUMA_SSL_CERT, and related environment variables to determine whether to establish an HTTPS connection when performing health checks against the server.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →