Self-Hosting on a Mini PC with Docker + Cloudflare Tunnel
How to safely expose multiple web services from a single mini PC at home. Attach HTTPS via Cloudflare Tunnel with zero open ports, and run everything with Docker Compose.
TL;DR
Run services on a mini PC with Docker Compose, and attach a domain and HTTPS via Cloudflare Tunnel (cloudflared) without opening any ports. No router config, no static IP, no certificate renewals.
On this page
Cloud bills add up surprisingly fast for small projects. I run several services, including this blog, on a single mini PC at home. Here's how.
Why a mini PC
- Always on, and electricity costs just a few dollars a month
- With Docker, the deployment environment is identical to the cloud
- If traffic grows, you can migrate then
There's exactly one problem: "how do I safely expose my home network to the outside?"
Don't open ports
The traditional route is router port forwarding + DDNS + certificate renewals. It's tedious, and it effectively opens your home network to the internet - risky.
Instead, use Cloudflare Tunnel. On the mini PC, cloudflared opens an outbound connection to Cloudflare, and traffic comes in through that tunnel. The number of inbound ports open to the outside: zero.
사용자 → Cloudflare(HTTPS) → 터널 → 미니 PC 의 컨테이너
- No public IP or port forwarding needed
- Cloudflare handles HTTPS certificates automatically
- A dynamic IP doesn't matter
Bundling services with Docker Compose
Each service runs as a container. For a Next.js app, build with output: "standalone" to keep the image light.
services:
blog:
build:
context: .
dockerfile: apps/blog/Dockerfile
container_name: why-next-blog
restart: unless-stopped
networks: [api]
networks:
api:
external: true # cloudflared 와 같은 네트워크
The key is putting it on the same Docker network as cloudflared. That's how the tunnel reaches the service by its container name.
Attaching a domain
In the Cloudflare dashboard (or the tunnel config), add one Public Hostname.
blog.example.com → http://why-next-blog:3001
That's it. Run docker compose up -d --build, and a few minutes later the site is live on your domain.
Wrapping up
- Mini PC + Docker = cheap, with deployments identical to the cloud
- Cloudflare Tunnel gives you HTTPS and a domain with zero open ports
- Place containers on the same network as cloudflared
- Map
domain → container:portvia Public Hostname
For small services, this combo alone holds up for a long time. It's how I keep several apps running while growing the things I've built.
Frequently asked questions
My home IP is dynamic - is that a problem?
Not at all. Cloudflare Tunnel works by having the mini PC open an outbound connection to Cloudflare, so you don't need a public IP, port forwarding, or DDNS.
Does it cost anything?
Cloudflare Tunnel itself is free. All you need to get started is the cost of a domain.
Related posts
- 💻 Dev
AI Writes the Code Now. So Why Does Git Matter More Than Ever?
If AI writes all the code, do I still need to learn Git? The question has it backwards: you need Git precisely because AI writes the code. A solo developer who builds almost everything with AI explains four reasons to get comfortable with Git and GitHub.
- 💻 Dev
I Blocked Double Execution - Then One Crash Locked It Forever
A status guard meant to stop duplicate background jobs ended up trapping a job in 'generating' forever when the process died mid-deploy. Every lock needs a way out, shipped in the same commit.
- 💻 Dev
Building an MDX Blog from Scratch with Next.js - How This Blog Was Made
How I built a blog that runs on nothing but markdown files, no CMS, using the Next.js 16 App Router. Folder structure, MDX setup, and SEO, walked through with the actual code.