Why NextWhy Next
Back to posts
💻 Dev3 min read

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:port via 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