Reverse proxy and HTTPS
Teldrive
Deployment

Reverse proxy and HTTPS

Put Teldrive behind a TLS reverse proxy without breaking cookies, uploads, or SSE.

Keep Teldrive private and terminate TLS at the proxy:

browser ──HTTPS──► proxy ──HTTP/private network──► Teldrive :8080

Trusted proxies

Trust only the address/CIDR of the proxy that connects directly to Teldrive:

http:
  trusted-proxies:
    - 127.0.0.1

Teldrive accepts X-Forwarded-Proto: https only from trusted peers. Do not use 0.0.0.0/0 or ::/0.

Caddy

Same host:

drive.example.com {
    reverse_proxy 127.0.0.1:8080
}
http:
  address: 127.0.0.1:8080
  trusted-proxies:
    - 127.0.0.1

For containerized Caddy, trust the actual container-network source CIDR instead.

Optional: tgdrive/caddy with varc

The tgdrive/caddy image includes varc, a sparse byte-range cache for large downloads and media seeking. Standard Caddy remains sufficient for HTTPS; caching is optional.

Add Caddy to the same private Compose network as Teldrive:

services:
  caddy:
    image: ghcr.io/tgdrive/caddy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
      - varc_cache:/var/cache/varc
volumes:
  caddy_data:
  caddy_config:
  varc_cache:

Save this as Caddyfile, replacing the domain:

drive.example.com {
    @stream {
        method GET HEAD
        path_regexp stream ^/api/v1/files/[0-9a-fA-F-]+/content(/[^/]+)?$
    }

    handle @stream {
        varc http://teldrive:8080{http.request.uri} {
            cache_dir /var/cache/varc
            key "{host}:{uri}:{http.request.header.Authorization}:{http.request.header.Cookie}"
            max_size 100GiB
            min_free_space 5GiB
            max_age 24h
            poll_interval 1m
            chunk_size 128MiB
            chunk_size_limit 1GiB
            chunk_streams 3
            read_ahead 16MiB
            buffer_size 16MiB
        }
    }

    handle {
        reverse_proxy teldrive:8080
    }
}

Set Teldrive’s listener to 0.0.0.0:8080 inside its container and trust only the private network used by Caddy. Do not publish Teldrive’s port publicly.

This caches GET/HEAD requests to /api/v1/files/{fileId}/content/{fileName} and the legacy /content URL. All other routes—including login, uploads, shares, and live events—use ordinary proxying. The dynamic upstream preserves query parameters. Cache keys include the URL and request credentials to separate authenticated representations; do not replace incoming credentials with a shared service token.

Varc forwards cookies/authorization and checks origin metadata before opening cached content. Test unauthenticated access and revoked credentials after warming the cache. Origin authentication errors may appear as cache-proxy errors rather than their original HTTP status.

Adjust the disk limits to your host and keep this volume private. Use one cache directory per Caddy process. See varc options for tuning.

Validate and start:

docker compose run --rm caddy caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
docker compose up -d caddy
docker compose logs --tail=100 caddy

The example follows current varc source; validation must use an image containing its dynamic-upstream support. It has not been exercised end-to-end here.

nginx

server {
    listen 443 ssl;
    server_name drive.example.com;

    ssl_certificate     /etc/letsencrypt/live/drive.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/drive.example.com/privkey.pem;

    client_max_body_size 0;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_request_buffering off;
        proxy_buffering off;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

Adjust timeouts for your deployment; file transfers and SSE require long-lived requests.

Container binding

services:
  teldrive:
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      TELDRIVE_HTTP_ADDRESS: 0.0.0.0:8080
      TELDRIVE_HTTP_TRUSTED_PROXIES: 172.18.0.0/16

Replace the example CIDR with the network your proxy actually uses.

Verify

After enabling HTTPS, test:

  • login and page refresh;
  • upload/download;
  • live task/progress updates;
  • no repeated SSE reconnects or cookie errors.

If a CDN/load balancer sits in front of your proxy, Teldrive should still trust only its direct proxy peer; that proxy must sanitize forwarding headers.