Contents
- Intro
- Architecture
- Cloudflare Tunnel
- Traefik Reverse Proxy
- Docker & Services
- Systemd Services
- Conclusion
Intro {#intro}
Setting up a homeserver that’s accessible from the internet requires careful consideration of security, SSL/TLS certificates, reverse proxying, and service management. This guide walks through a production-ready setup using:
- Cloudflare Tunnel for secure external access with automatic TLS/SSL
- Traefik as a reverse proxy for routing and load balancing
- Docker for containerized services
- Nginx for serving static sites
- systemd for service management
Architecture {#architecture}
The setup follows this architecture:
Internet → Cloudflare Tunnel → Traefik → Services (Docker containers, Nginx)
↓
SSL/TLS termination
Routing & load balancing
Key components:
- Cloudflare Tunnel handles external access and provides TLS certificates
- Traefik acts as reverse proxy, routing requests to appropriate services
- Docker runs containerized applications (databases, apps, etc.)
- Nginx serves static websites
- systemd manages all services as system daemons
Cloudflare Tunnel {#cloudflare}
Cloudflare Tunnel (formerly Argo Tunnel) creates a secure connection from your server to Cloudflare’s edge network without opening inbound ports.
Setup Steps
- Install cloudflared:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb
- Authenticate:
cloudflared tunnel login
- Create tunnel:
cloudflared tunnel create myserver
- Configure routing in
config.yml:
tunnel: <tunnel-id>
credentials-file: /root/.cloudflared/<tunnel-id>.json
ingress:
- hostname: example.com
service: http://localhost:8080
- service: http_status:404
- Run as systemd service:
sudo cloudflared service install
sudo systemctl start cloudflared
sudo systemctl enable cloudflared
Traefik Reverse Proxy {#traefik}
Traefik automatically discovers services and configures routing.
docker-compose.yml
version: '3.8'
services:
traefik:
image: traefik:v2.10
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
restart: unless-stopped
Docker & Services {#docker}
Example service with Traefik labels:
services:
whoami:
image: traefik/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
- "traefik.http.routers.whoami.entrypoints=web"
restart: unless-stopped
Systemd Services {#systemd}
Create a systemd service for your Docker Compose stack:
[Unit]
Description=Homeserver Docker Services
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/homeserver
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl enable homeserver
sudo systemctl start homeserver
Conclusion {#conclusion}
This setup provides:
- ✅ Secure external access without port forwarding
- ✅ Automatic TLS/SSL certificates
- ✅ Easy service discovery and routing
- ✅ Containerized applications
- ✅ System-level service management
For more details, check out the Cloudflare Tunnel docs and Traefik documentation.