Managed infrastructure for SMBs
Reverse Proxy and HTTPS for Self-Hosted Apps on a VPS: Caddy, Nginx and Docker
The short answer
A reverse proxy is one small web server that sits in front of everything else on your VPS. It answers on ports 80 and 443, holds the HTTPS certificates, and passes each request to the right app based on the domain name. That lets you run a dashboard, a wiki, a booking tool and a website on one server, each on its own subdomain with a padlock, while the apps themselves stay off the public internet. This guide covers how to set that up safely on a Linux VPS.
1. Know when you need one
You want a reverse proxy as soon as you run more than one web app on a server, or any app that listens on its own port such as 3000, 8080 or 8443. Without one, people end up typing ports into URLs, apps run without HTTPS, and every app has to be opened in the firewall. With one, the outside world only ever sees ports 80 and 443.
2. Pick a proxy you can maintain
- Caddy is the simplest choice for most small teams. A few lines per site, and it requests and renews HTTPS certificates on its own.
- Nginx is the common choice if you already know it. Pair it with Certbot for certificates, as covered in our TLS certificate renewal guide.
- Traefik fits servers where most apps run in Docker, because it can read container labels and route to new containers automatically.
Pick one and use it for every app on the server. Two proxies competing for port 443 is a common cause of confusing outages.
3. Plan your names first
Give each app its own subdomain, such as wiki.example.com and status.example.com, and point each DNS A record (and AAAA, if you use IPv6) at the VPS. Subdomains are easier to secure and move later than paths like example.com/wiki, which many apps do not handle well. Replace the example names with your own.
4. Keep the apps private
Each app should listen only on 127.0.0.1 or on a private Docker network, never on every interface. In Docker Compose, publish ports as 127.0.0.1:8080:8080 instead of 8080:8080, or skip publishing and let the proxy reach the container by name on a shared network. Then check from another machine that the app's port does not answer directly. This is the step people most often skip, and it leaves an unprotected copy of the app open next to the proxied one.
5. Add the first site
With Caddy, a site block can be as short as wiki.example.com { reverse_proxy 127.0.0.1:8080 }. Reload Caddy and it fetches the certificate on the first request. With Nginx, create a server block for the subdomain with a location / that uses proxy_pass http://127.0.0.1:8080;, run sudo nginx -t, reload, then run Certbot for that name.
6. Pass the right headers
Apps need to know the original visitor and that the request came in over HTTPS, or they build wrong links and redirect loops. Caddy sends these by default. With Nginx, set Host, X-Real-IP, X-Forwarded-For and X-Forwarded-Proto. Many apps also have a setting for their public URL or trusted proxies; set it to the HTTPS address so logins and links work.
7. Handle WebSockets and uploads
Chat tools, dashboards and many admin panels use WebSockets. Caddy handles them automatically. In Nginx, add the Upgrade and Connection headers for that location. If people upload files, raise the request size limit (in Nginx, client_max_body_size) to match what the app allows, or uploads fail with a 413 error.
8. Lock down the edges
- Allow only ports 22 (or your SSH port), 80 and 443 in the firewall, and secure SSH as described in how to secure SSH on a Linux VPS.
- Redirect HTTP to HTTPS for every site.
- Put admin-only apps behind an extra layer, such as a VPN, an IP allowlist or the proxy's basic authentication, on top of the app's own login.
- Keep the proxy and the apps updated; the proxy is the part everyone on the internet can reach.
9. Watch it from the outside
Add each public subdomain to your uptime monitoring and alert on both downtime and certificate expiry. A proxy can look healthy while one app behind it returns errors, so check each site's real page, not just the server. Our VPS monitoring and alerts guide covers how to route alerts to the right person.
10. Back up the config and write it down
Keep the proxy config (the Caddyfile or Nginx site files) and your Docker Compose files in your backups, and keep a short list of which subdomain goes to which app and port. When you rebuild or move the server, that list and those files turn a long evening into a short one. See VPS backups and snapshots for a simple plan.
Quick checklist
- One proxy on ports 80 and 443
- One subdomain per app, DNS pointed at the VPS
- Apps bound to 127.0.0.1 or a private Docker network
- Forwarded headers and the app's public URL set
- WebSockets and upload size handled
- Firewall limited to SSH, 80 and 443; admin apps behind an extra layer
- Uptime and certificate alerts per subdomain
- Proxy and Compose files in backups, plus a routing list
Running apps in containers? Start with Docker on a Linux VPS, and if you are still deciding on a server, read how to choose a VPS size.
Next steps
If you would rather not run the proxy, certificates and updates yourself, our managed services can look after the server and the apps on it. Read managed vs unmanaged VPS to compare, browse the plans, then tell us what you run or email sales@glasshosting.com.
Host with GlassHosting
Order a plan or browse the knowledgebase for deeper how-tos.