Hostingupdated 9 Oct 2026

How waterside.work is hosted

One VPS, four layers — and which one to suspect when something breaks.

Everything on waterside.work runs on a single virtual private server. There is no platform in between: the same machine builds the sites, holds the certificates and answers the requests.

It helps to think of it as four layers, each with one job. When something breaks, the first question is always which layer?

The four layers

Layer Tool Its one job
Containers Docker Run each site or service in its own isolated box
Routing Traefik Read the hostname on each request and send it to the right box
Certificates Let’s Encrypt Prove each hostname is ours, so browsers trust the HTTPS
Deploys Coolify Watch a git branch, build on push, start the new container

Docker means every project gets its own filesystem and dependencies. A Laravel app and an Astro site can sit side by side without knowing about each other.

Traefik is the only thing listening on ports 80 and 443. Every request carries a Host header — waterside.work, preview.waterside.work — and Traefik matches it against rules attached to each container. That is how one IP address serves many sites.

Let’s Encrypt issues a free certificate for each hostname the first time Traefik sees a rule for it, and renews it before it expires. Nothing to buy, nothing to remember.

Coolify is the control panel on top. It writes the Traefik rules, runs the builds and keeps a history of deploys. It is convenient — but it is the layer least needed to understand a failure, because the other three are doing the actual work.

Which layer is it?

  • The browser says the certificate is invalid. Let’s Encrypt has not issued one yet — usually because the hostname does not resolve here, or port 80 was unreachable during the check.
  • A plain “404 page not found” in monospace. Traefik is answering but has no rule for that hostname. The container is missing, stopped, or labelled wrong.
  • “Bad gateway”. Traefik has a rule, but the container behind it is not answering on the port it expected.
  • The old version is still showing. The deploy layer: check whether the build actually ran and succeeded.

Public and internal

This site is built twice from one repository. The public build — the one you are reading — contains only public docs. A second build with internal runbooks is served on its own hostname, behind a login. The private pages are never part of this build at all, rather than merely hidden from it.