Skip to content
Preview. LawFive's code and server image aren't public yet, so some steps here won't work until they are.

Set up HTTPS

LawFive speaks plain HTTP on port 3000. Something in front of it holds the certificate. LawFive doesn’t manage certificates itself.

Your server has this same guide built in, with your domain filled in, under Settings → Server → HTTPS. It also tells you when it’s set up correctly.

Method Best for The trade-off
Caddy The simplest with your own domain. It gets and renews the certificate itself. Ports 80 and 443 must reach this machine, and nothing else may be using them.
Traefik A machine that already runs Traefik. Names must match your Traefik setup.
nginx and Certbot A machine that already runs nginx, outside Docker. nginx and Certbot are yours to keep updated.
Cloudflare Tunnel A server at home: no open ports, behind any router. The domain must be on Cloudflare, it can see the traffic, and uploads are limited to 100 MB on its free plan.
Tailscale Funnel No domain of your own: you get a free .ts.net address. Funnel must be allowed in your tailnet, and the address has Tailscale’s name in it.

The examples use lawfive.example.com. Replace it with your own domain.

  1. Point your domain at this machine’s public address in DNS. If it’s behind a router, forward ports 80 and 443 to it.

  2. Add Caddy beside the server, in a new file next to compose.yaml:

    compose.override.yaml
    services:
    caddy:
    image: caddy:2
    restart: unless-stopped
    command: caddy reverse-proxy --from lawfive.example.com --to server:3000
    ports:
    - "80:80"
    - "443:443"
    - "443:443/udp"
    volumes:
    - caddy-data:/data
    volumes:
    caddy-data:
  3. Finish up.

  1. Point your domain at your Traefik machine in DNS.

  2. Give the server Traefik’s labels and network, in a new file next to compose.yaml. The network, entry point and certificate resolver must use the names in your Traefik setup.

    compose.override.yaml
    services:
    server:
    labels:
    - traefik.enable=true
    - traefik.http.routers.lawfive.rule=Host(`lawfive.example.com`)
    - traefik.http.routers.lawfive.entrypoints=websecure
    - traefik.http.routers.lawfive.tls.certresolver=letsencrypt
    - traefik.http.services.lawfive.loadbalancer.server.port=3000
    networks:
    - default
    - traefik
    networks:
    traefik:
    external: true
  3. Finish up.

  1. Point your domain at this machine’s public address in DNS. If it’s behind a router, forward ports 80 and 443 to it.

  2. Add a site to nginx. The size limit allows restoring a large export, and turning buffering off lets one download as it’s made.

    /etc/nginx/conf.d/lawfive.example.com.conf
    server {
    listen 80;
    server_name lawfive.example.com;
    client_max_body_size 2g;
    location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    }
    }
  3. Get the certificate. Certbot adds it to that site, and renews it by itself once installed.

    Terminal window
    sudo certbot --nginx -d lawfive.example.com
  4. Finish up.

  1. In Cloudflare’s Zero Trust dashboard, make a tunnel under Networks, and copy its token. Add a public hostname of your domain, with the service http://server:3000.

  2. Run the tunnel beside the server, in a new file next to compose.yaml:

    compose.override.yaml
    services:
    cloudflared:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel run
    environment:
    TUNNEL_TOKEN: ${CLOUDFLARE_TUNNEL_TOKEN}
  3. Add these to .env. The first makes limits on wrong passwords count each visitor rather than Cloudflare.

    .env
    TRUSTED_IP_HEADER=CF-Connecting-IP
    CLOUDFLARE_TUNNEL_TOKEN=the-token-from-cloudflare
  4. Finish up.

  1. Install Tailscale on this machine and sign in, then share the server. It prints your address.

    Terminal window
    tailscale funnel --bg 3000
  2. Finish up, using the address it printed, such as https://your-machine.your-tailnet.ts.net.

  1. Tell LawFive its new address, and keep port 3000 to this machine, in .env:

    .env
    PUBLIC_URL=https://lawfive.example.com
    PORT=127.0.0.1:3000
  2. Start it all again:

    Terminal window
    docker compose up -d
  3. Open your new address and sign in again. Settings → Server → HTTPS says when it’s right.

Phones and watches linked to the old address need signing in or linking again.

If another proxy such as Cloudflare sits in front of your reverse proxy, set TRUSTED_IP_HEADER to the header it puts the visitor’s address in. For Cloudflare, that’s CF-Connecting-IP. Without it, limits on wrong passwords count everyone arriving through that proxy together.

If phones should reach the API at a different address from the website, set API_URL. Most servers leave it unset.