HTTPS & Domain Lock
Out of the box Pinchy accepts requests on any host over plain HTTP. That’s fine for local development but unsafe in production. This guide walks you through two steps that secure your instance: HTTPS via a reverse proxy (so all traffic is encrypted) and Domain Lock (so Pinchy only responds to your chosen domain).
Set up HTTPS with Caddy
Section titled “Set up HTTPS with Caddy”HTTPS encrypts all traffic between browsers and your server. Pinchy doesn’t handle TLS itself — a reverse proxy sits in front of it and takes care of certificates. We recommend Caddy because it automatically gets and renews Let’s Encrypt certificates with zero configuration.
Install Caddy
Section titled “Install Caddy”apt-get install -y caddyConfigure your domain
Section titled “Configure your domain”Make sure your domain’s DNS A record points to your server’s IP address. Then edit the Caddy configuration:
nano /etc/caddy/CaddyfileReplace the contents with (use your actual domain):
pinchy.example.com { reverse_proxy localhost:7777}Save the file (Ctrl+O, Enter, Ctrl+X in nano) and restart Caddy:
systemctl restart caddyCaddy automatically provisions Let’s Encrypt certificates for your domain. After a few seconds, visit https://pinchy.example.com — you should see Pinchy with a valid HTTPS certificate.
What’s a reverse proxy and why do I need one?
A reverse proxy sits between the internet and Pinchy. When someone visits your domain:
- Their browser connects to Caddy on port 443 (HTTPS)
- Caddy handles the SSL certificate and encryption
- Caddy forwards the request to Pinchy on port 7777 (internal only)
- Pinchy sends the response back through Caddy
This way, Pinchy never needs to deal with SSL certificates directly.
See the Hardening Guide for nginx examples and advanced configuration.
What domain lock does
Section titled “What domain lock does”Once HTTPS is working, the next step is locking Pinchy to that domain. Domain Lock pins your instance to exactly one HTTPS domain and turns on the rest of the production security profile as a package:
- Only requests whose
Hostheader matches the locked domain reach the app. Everything else gets a403 Access Deniedpage. - Cookies are issued with
SecureandSameSite=Lax. - HSTS is advertised so modern browsers refuse to connect over plain HTTP.
- Origin checks are enforced on state-changing requests.
You don’t have to configure any of these individually — locking the domain flips them all on.
Lock the domain
Section titled “Lock the domain”- Sign in as an admin on the HTTPS domain you want to lock to
- Go to Settings → Security
- The page shows your current host and whether the connection is HTTPS
- Click Lock to this domain
- Pinchy restarts briefly to apply the new security profile — the page will reload automatically
From this point on, only the locked domain can reach the app.
Remove the lock
Section titled “Remove the lock”If the business needs change (different domain, temporary maintenance URL, etc.):
- Go to Settings → Security
- Click Remove domain lock
- Confirm — the restart happens the same way as on lock
Recover from a lockout
Section titled “Recover from a lockout”If HTTPS goes down (expired certificate, proxy misconfiguration, DNS change) you can find yourself unable to reach the admin UI at all. Pinchy includes a last-resort CLI to clear the lock from inside the container:
docker exec pinchy pnpm domain:resetThe command needs shell access to the Pinchy container, so protect it like any other production admin credential. After it runs, Pinchy accepts any host again and you can reach the UI on the non-HTTPS or fallback URL to diagnose the underlying problem.
What about local development?
Section titled “What about local development?”Don’t use domain lock in development. It is designed for a single deployed instance on a known domain, not for localhost or Docker dev stacks. The Security tab is still visible but it refuses to lock when the current connection is not HTTPS.