Skip to content

Remote access & HTTPS

A VPN puts your phone or laptop “inside” your home network, so you open PetHealth exactly as you do at home (e.g. http://192.168.1.50:3000) and nothing is exposed publicly.

  • Tailscale: the easiest option. Install it on the server and on your devices, sign in with the same account, and open http://<server-tailscale-name>:3000. You don’t need to open router ports.
  • WireGuard: self-managed. Many routers, NAS systems (Synology, Unraid, TrueNAS) and firewalls (OPNsense, pfSense) include it.
  • Your router’s built-in VPN server works too.

Set APP_URL to the address you use to open PetHealth, so links in emails point to it:

APP_URL=http://192.168.1.50:3000

Plain HTTP is fine on a trusted home network or inside a VPN. If you want HTTPS anyway (for example with a local name like pets.home.arpa), put a reverse proxy in front of PetHealth and set:

TRUST_PROXY=true
APP_URL=https://pets.home.arpa
  • TRUST_PROXY=true makes PetHealth use the client’s real IP (from X-Forwarded-For) for login rate limiting, and mark the file cookie Secure when the original request was HTTPS.
  • PetHealth listens on port 3001 inside the container. The examples assume the proxy reaches it as pethealth:3001 on a shared Docker network.
pets.home.arpa {
tls internal
reverse_proxy pethealth:3001
}

tls internal makes Caddy sign the certificate with its own local CA. Install Caddy’s root certificate on your devices to avoid browser warnings.

server {
listen 443 ssl;
server_name pets.home.arpa;
ssl_certificate /etc/nginx/certs/pets.home.arpa.crt;
ssl_certificate_key /etc/nginx/certs/pets.home.arpa.key;
client_max_body_size 200m; # pet imports can be up to 200 MB
location / {
proxy_pass http://pethealth: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;
}
}

If you won’t import pets, client_max_body_size 20m is enough (photos 5 MB, PDFs 15 MB, attachments 10 MB).

PetHealth expects to be served at the root of a host (https://pets.home.arpa/). Serving it under a subpath like /pethealth/ isn’t supported; use its own host name or port.