← Back to blog

Self-Hosting Five Projects on an Old MacBook Behind One Cloudflare Tunnel

Five of my side projects - including this site - run on a single old MacBook at home, behind one Cloudflare Tunnel with no open ports. Here's the architecture and why I moved everything off cloud VMs.

  • self-hosting
  • cloudflare tunnel
  • docker
  • caddy
  • home server
  • homelab
# Self-Hosting Five Projects on an Old MacBook Behind One Cloudflare Tunnel Five of my side projects run on a single old MacBook sitting at home. It runs Ubuntu Server and Docker, and the page you're reading right now is served from it. Here's how that works, and why I moved everything there. ## One way in: a Cloudflare Tunnel The machine has no open ports. There's no port-forwarding rule on my home router, and nothing on the box is directly reachable from the internet. Instead, a single Cloudflare Tunnel runs on the machine and makes *outbound* connections to Cloudflare's edge. All public traffic arrives at Cloudflare first and is handed back down through that tunnel. This flips the usual self-hosting threat model. There's no inbound attack surface to harden, no public SSH or HTTP port to defend, no fail2ban arms race. If it isn't routed through the tunnel, it can't reach the box. ## TLS at the edge, plain HTTP inside TLS terminates at Cloudflare's edge. I don't run a single certificate on the machine and I never renew one. Inside the house, every project runs its own Caddy reverse proxy listening on plain HTTP (port 80) on a shared Docker network I call `edge`. The tunnel routes each public hostname to the right project's Caddy container over that network. So the request path for any site is: ``` browser -> Cloudflare edge (TLS) -> tunnel -> project's Caddy (:80 on `edge`) -> app container ``` ## Everything is a Compose stack Each project is a Docker Compose stack under `/opt/stacks/<project>/`. The tunnel itself is just another stack at `/opt/stacks/edge/`. There's nothing special about any one project from the host's point of view - they're all stacks on the same `edge` network, and the tunnel is the single front door for all of them. ## Why I left the VMs All of these projects used to run on Hetzner VMs. I decommissioned them and consolidated everything onto the MacBook. The VMs were more machine - and more monthly cost - than these projects actually needed. One laptop I already owned was cheaper to run and simpler to reason about than a handful of cloud instances, and the tunnel meant I didn't have to expose my home network to get them online. ## What the model buys me - **No inbound surface.** Nothing on the machine is exposed except through the tunnel. - **Uniform onboarding.** Adding a project means dropping a Compose stack with an HTTP-only Caddy on the `edge` network and adding one ingress route to the tunnel config. - **One quiet laptop** runs the whole fleet. If you're weighing a homelab or a Cloudflare Tunnel setup for your own projects - or wondering whether to pull side projects off cloud VMs - I'm happy to compare notes. Reach out via my portfolio at [tahayusufkomur.me](https://tahayusufkomur.me).