Self-Hosting a Dockerized App on WSL2, Exposed with a Cloudflare Tunnel
TL;DR: A proof-of-concept to-do app — Node/Express and Postgres, running in Docker on WSL2 — reachable at a real domain through a named cloudflared tunnel. No login system, just a per-browser cookie hash. If you already have WSL2 and a Cloudflare-managed domain, expect this to take a few minutes, not hours. I wanted a small proof of concept: a to-do list with real persistence, running in Docker,…
The article provides a step-by-step guide on how to self-host a Dockerized to-do app on Windows Subsystem for Linux 2 (WSL2) and expose it using a Cloudflare tunnel. The author shares their experience with this process and highlights a few lessons learned along the way.
Firstly, the setup requires a Windows OS with WSL2 and an Ubuntu distro installed. Docker Engine should be installed inside WSL2, not Docker Desktop. A domain managed in Cloudflare is also necessary to route a subdomain to the cloudflared tunnel.
The app itself is a simple Node.js and Express-based to-do list running in Docker, with Postgres used for persistence. Each visitor gets an httpOnly cookie with a random hash, which filters queries and gives them a separate list per browser without any real authentication. The table is cleared every two hours, with a warning in the UI to avoid any surprises.
Two deployment methods were tested: a bare Dockerfile connecting to the Postgres instance already running on the Windows host, and a docker-compose.yml with its own Postgres container and a crond sidecar container for periodic cleanup. The latter approach was chosen, as it turned out to be a more straightforward solution.
The main challenge encountered during the process was the networking issue when moving Docker from Docker Desktop to WSL2, as the hostname host.docker.internal could not resolve cleanly. To overcome this, the author decided to use the docker-compose path instead, which resolved the issue.
Finally, the app was exposed to the public internet using a Cloudflare tunnel. The process involved creating a tunnel with cloudflared, configuring it with the tunnel ID, and then running the tunnel. It is important to note that cloudflared.exe, being a Windows binary, interprets paths differently than Linux, so Windows-style paths should be used when invoking it from WSL2.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.