Getting in

Reaching your stack from outside the house.

Reverse proxy, VPN, tunnels and authentication. Including the containers that should never be published, and why.

Your options

There are three ways to reach your stack from outside, and they are not equally safe. Pick by who needs access, not by which is easiest to set up.

ApproachWho can reach itNeeds
VPNOnly devices you enrolA port forward, or a mesh service
TunnelAnyone with the URL, plus whatever auth you addAn account with the tunnel provider
Reverse proxy on a public IPAnyone on the internetA domain, a port forward, and real care

The honest default for a personal workspace server is a VPN. Nothing is exposed, there is no login page for anyone to attack, and every app behaves as though you were at home. Publish only the specific things other people genuinely need to open.

Reverse proxy

The proxy's job is TLS and hostname routing. Give each service a subdomain and let the proxy hold the certificate.

A Caddy site block is two lines:

wiki.example.com {
    reverse_proxy bookstack:80
}

Three things go wrong often enough to name:

  • The app needs to know its own URL. BookStack has APP_URL, Paperless-ngx has PAPERLESS_URL, Homarr infers it from forwarded headers. Set it, or you get redirects back to localhost and broken links in emails.
  • WebSockets. CryptPad, Wiki.js, AppFlowy and Jitsi all need them passed through. Caddy and Traefik do this by default; Nginx needs the upgrade headers set explicitly.
  • Certificate validation. The Selkies-based containers serve their own self-signed certificate on port 3001, so a proxy that validates upstream certificates will refuse them. Their HTTP port exists for exactly this case.

VPN

Two shapes, and the difference is whether you open a port.

WireGuard on your own server means one UDP port forwarded and a config file per device. It is fast, it is small, and it depends on nobody. It needs a port forward, which means it needs a router you control and an address that does not change, or dynamic DNS.

A mesh VPN such as Tailscale or Netbird does the same job without a port forward, by having both ends connect out to a coordination service. Easier, works behind carrier-grade NAT, and the tradeoff is that a third party brokers your connections. Both have self-hostable coordination servers if that matters to you.

This is the cheap answer. A VPN costs nothing, needs no domain, and removes the entire question of which apps are safe to expose. If you are the only person using the stack, stop here.

Tunnels

A tunnel service gives you a public hostname without a port forward or a static IP. An agent on your machine connects out, and traffic comes back down that connection. Cloudflare Tunnel is the common choice; there are others.

Two things to weigh. The provider terminates TLS, so they can see your traffic. And providers have terms about what may be served through a free tunnel, particularly around large media files. Read the current terms rather than a blog post about them, because the wording has changed more than once and old summaries circulate long after they stop being true.

For a workspace server, tunnels fit well: the traffic is documents and web pages, not bulk media. If you want a public URL for one shared thing, a tunnel in front of that one service is a reasonable answer.

Authentication

Proxying is not authenticating. If a service has no login, putting it on a subdomain with a valid certificate just means the world can reach it over HTTPS.

Three layers, weakest first:

  1. Basic auth at the proxy. One shared password, no sessions, no recovery. Fine for a single admin tool on a home network, nothing more.
  2. A forward-auth gateway. Authelia or Authentik sit beside the proxy and require a login before any request reaches the app. This is the right answer for apps with weak or no built-in authentication.
  3. The app's own accounts, plus SSO. Best where available. Forgejo can act as an OAuth2 provider for other services, which is worth knowing if you are running it anyway. PdfDing, BookStack, Homarr and Dashy all support OIDC.
Stirling-PDF's SSO is not in the free tier. Single sign-on sits in the paid Server plan. If you need Stirling behind a login without paying, use a forward-auth gateway rather than assuming the built-in accounts will do it.

What never gets published

Some containers in this list should not be published to the internet, with or without a proxy in front of them. If the generator writes you a reverse-proxy config, these are excluded from it, and the config says why.

ModuleWhy
Obsidian (LinuxServer)Streamed desktop with a terminal and passwordless sudo. No authentication by default
Calligra (LinuxServer)Same base image, same exposure
Anything with the Docker socketThe socket is root on the host, in practical terms
Take the Selkies warning literally. LinuxServer's own documentation says these containers provide privileged access to the host system, that the web interface includes a terminal with passwordless sudo, and that anyone who can reach the GUI can gain root inside the container. It tells you to treat a session like an SSH login to a machine on your network, because that is what it is. Reach them over your VPN.

The Docker socket deserves its own note because it appears innocently. Homarr asks for it to show container status, and dashboards generally do. Mounting /var/run/docker.sock gives that container control of the Docker daemon, which is equivalent to root on the host. Mount it read only when you do mount it, understand that read only limits the damage rather than removing it, and leave it out entirely if you do not need live container status.

One more, which is about data rather than exposure. CryptPad needs two different origins, a main domain and a sandbox domain with restrictive content-security-policy headers. Its documentation states that running without the sandbox may put users' information at risk. A single-hostname CryptPad install is not a working CryptPad install.