# How to Configure SSL/TLS for Uptime Kuma: Native HTTPS and Reverse Proxy Methods

> Secure your Uptime Kuma monitoring with native HTTPS or a reverse proxy. This guide explains SSL/TLS configuration for enhanced security and accessibility.

- Repository: [Louis Lam/uptime-kuma](https://github.com/louislam/uptime-kuma)
- Tags: how-to-guide
- Published: 2026-02-28

---

**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`](https://github.com/louislam/uptime-kuma/blob/main/server/config.js) and [`server/uptime-kuma-server.js`](https://github.com/louislam/uptime-kuma/blob/main/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`](https://github.com/louislam/uptime-kuma/blob/main/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:

```bash
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`](https://github.com/louislam/uptime-kuma/blob/main/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:

```bash
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`](https://github.com/louislam/uptime-kuma/blob/main/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`](https://github.com/louislam/uptime-kuma/blob/main/server/config.js) exports an `isSSL` boolean that determines the server type:

```javascript
// 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`](https://github.com/louislam/uptime-kuma/blob/main/server/uptime-kuma-server.js), the application creates an HTTPS server when `isSSL` is true:

```javascript
// 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

```nginx
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`](https://github.com/louislam/uptime-kuma/blob/main/src/components/settings/ReverseProxy.vue) and a footer link in [`src/layouts/Layout.vue`](https://github.com/louislam/uptime-kuma/blob/main/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-key` and `--ssl-cert` flags (or `UPTIME_KUMA_SSL_KEY`/`UPTIME_KUMA_SSL_CERT` environment 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.js`](https://github.com/louislam/uptime-kuma/blob/main/server/config.js) file handles all TLS option parsing and exports `isSSL`, `sslKey`, `sslCert`, and `sslKeyPassphrase` to [`server/uptime-kuma-server.js`](https://github.com/louislam/uptime-kuma/blob/main/server/uptime-kuma-server.js).
- **Health Checks**: The [`extra/healthcheck.js`](https://github.com/louislam/uptime-kuma/blob/main/extra/healthcheck.js) utility 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`](https://github.com/louislam/uptime-kuma/blob/main/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`](https://github.com/louislam/uptime-kuma/blob/main/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`](https://github.com/louislam/uptime-kuma/blob/main/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.