Skip to content

About

Proxmox LXC OCI image with Traefik, Cloudflared, and DDNS for homelab reverse proxy

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

Β 

History

1 Commit

Folders and files

Repository files navigation

πŸ”’ DNS Reverse Proxy - Proxmox LXC Container

Build OCI Image

A production-ready OCI image for Proxmox LXC that bundles Traefik (with Cloudflare DNS challenge), Cloudflared (Argo Tunnels), and Favonia/Cloudflare DDNS into a single Alpine-based container acting as your central reverse proxy.


πŸ“‹ Table of Contents

  1. Features
  2. Architecture Overview
  3. Prerequisites
  4. Quick Start
  5. Building the Image
  6. Importing into Proxmox
  7. Configuration
  8. Adding Applications
  9. Networking Guide
  10. Security Checklist
  11. Troubleshooting
  12. License

✨ Features

  • Alpine Linux (latest) - Minimal footprint (~50MB base)
  • Traefik v3 - Modern reverse proxy with automatic HTTPS via Let's Encrypt
  • Cloudflare DNS Challenge - Wildcard certificates without exposing port 80
  • Cloudflared Tunnel - Zero-trust access without opening firewall ports
  • Favonia DDNS - Automatic DNS record updates for dynamic IPs
  • Supervisor - Process management for all services
  • OCI Compliant - Works with Docker, Podman, Buildah, and Proxmox

πŸ— Architecture Overview

                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚           Proxmox LXC "dns"             β”‚
                                    β”‚                                         β”‚
Internet ─── Cloudflare ───────────►│  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
              (DNS/CDN)             β”‚  β”‚ Cloudflared β”‚  β”‚     Traefik      β”‚  β”‚
                                    β”‚  β”‚   Tunnel    │──│   (Port 443)     β”‚  β”‚
                                    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
                                    β”‚                            β”‚            β”‚
                                    β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”‚            β”‚
                                    β”‚  β”‚ Favonia     β”‚           β”‚            β”‚
                                    β”‚  β”‚ DDNS Script β”‚           β–Ό            β”‚
                                    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     Internal Apps      β”‚
                                    β”‚                      (VLAN/Bridge)      β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“¦ Prerequisites

Cloudflare Setup

  1. Domain registered with Cloudflare (free tier works)

  2. API Token with these permissions:

    • Zone:Zone:Read - List zones
    • Zone:DNS:Edit - Manage DNS records (for DDNS + ACME)

    ⚠️ Security: Create a scoped token, NOT a Global API Key!

  3. Cloudflare Tunnel (optional but recommended):

    • Install cloudflared locally
    • Run cloudflared tunnel login
    • Run cloudflared tunnel create dns-tunnel
    • Save the credentials JSON file

Proxmox Setup

  • Proxmox VE 9.x
  • Storage with "Container Template" content type enabled
  • Network bridges configured (e.g., vmbr0 for WAN, vmbr1 for internal VLAN)

πŸš€ Quick Start

# 1. Clone this repository
git clone https://github.com/harshsinghmp/dns-reverse-proxy.git
cd dns-reverse-proxy

# 2. Copy and edit environment file
cp .env.example .env
nano .env  # Fill in your Cloudflare credentials

# 3. Build the OCI image
docker build -t dns-reverse-proxy:latest .

# 4. Export for Proxmox
docker save dns-reverse-proxy:latest | gzip > dns-reverse-proxy.tar.gz

# 5. Upload to Proxmox and import (see detailed steps below)

πŸ”§ Building the Image

Option 1: Docker (Local)

# Build the image
docker build -t dns-reverse-proxy:latest .

# Optional: Test locally before exporting
docker run -it --rm \
  -p 80:80 -p 443:443 \
  -v $(pwd)/config:/etc/traefik \
  -v $(pwd)/data:/data \
  --env-file .env \
  dns-reverse-proxy:latest

# Export as OCI archive for Proxmox
docker save dns-reverse-proxy:latest -o dns-reverse-proxy.tar
gzip dns-reverse-proxy.tar

Option 2: Podman (Rootless)

# Build with Podman
podman build -t dns-reverse-proxy:latest .

# Export as OCI archive
podman save dns-reverse-proxy:latest -o dns-reverse-proxy.tar
gzip dns-reverse-proxy.tar

Option 3: Buildah (No Daemon)

# Build with Buildah
buildah bud -t dns-reverse-proxy:latest .

# Export as OCI archive
buildah push dns-reverse-proxy:latest oci-archive:dns-reverse-proxy.tar
gzip dns-reverse-proxy.tar

Option 4: GitHub Actions (Recommended - No Local Docker Needed)

The included GitHub Actions workflow builds the image automatically:

  1. Fork this repository
  2. Add secrets in Settings > Secrets and variables > Actions:
    • GITHUB_TOKEN (auto-provided)
  3. Push to main branch or create a release tag
  4. Download artifact from the Actions tab
# The workflow will:
# - Build the OCI image on Ubuntu runner
# - Export as .tar.gz artifact
# - Upload to GitHub Container Registry (optional)

To download the built image:

# From GitHub Container Registry
docker pull ghcr.io/harshsinghmp/dns-reverse-proxy:latest
docker save ghcr.io/harshsinghmp/dns-reverse-proxy:latest -o dns-reverse-proxy.tar
gzip dns-reverse-proxy.tar

πŸ“₯ Importing into Proxmox

Step 1: Upload the OCI Archive

# Option A: SCP from local machine
scp dns-reverse-proxy.tar.gz root@proxmox:/var/lib/vz/template/cache/

# Option B: Download directly on Proxmox
ssh root@proxmox
cd /var/lib/vz/template/cache/
wget https://github.com/harshsinghmp/dns-reverse-proxy/releases/download/v1.0.0/dns-reverse-proxy.tar.gz

Step 2: Convert OCI to Proxmox Template

Proxmox doesn't natively import Docker/OCI images. Use this method:

# SSH into Proxmox host
ssh root@proxmox

# Create a temporary directory
mkdir -p /tmp/oci-import && cd /tmp/oci-import

# Extract the OCI image
tar -xzf /var/lib/vz/template/cache/dns-reverse-proxy.tar.gz

# Install skopeo if not present (for conversion)
apt update && apt install -y skopeo

# Convert Docker archive to rootfs
# Method: Extract layers and create LXC template
mkdir rootfs
for layer in $(cat manifest.json | jq -r '.[0].Layers[]'); do
  tar -xf "$layer" -C rootfs
done

# Create the LXC template
cd rootfs
tar -czf /var/lib/vz/template/cache/dns-reverse-proxy-lxc.tar.gz .

# Cleanup
rm -rf /tmp/oci-import

Step 3: Create the LXC Container

# Via Proxmox CLI
pct create 100 /var/lib/vz/template/cache/dns-reverse-proxy-lxc.tar.gz \
  --hostname dns \
  --memory 512 \
  --cores 2 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --net1 name=eth1,bridge=vmbr1,ip=10.10.10.2/24 \
  --rootfs local-lvm:8 \
  --ostype alpine \
  --unprivileged 1 \
  --features nesting=1 \
  --mp0 /mnt/data/containers/reverse-proxy,mp=/data \
  --start 0

# Or via Proxmox Web UI:
# 1. Datacenter > Storage > local > CT Templates
# 2. Upload the .tar.gz file
# 3. Create CT with template selection

Alternative: Use Alpine Template + Manual Setup

If OCI import is problematic, use the official Alpine template:

# Download Alpine template
pveam update
pveam download local alpine-3.19-default_20231211_amd64.tar.xz

# Create LXC
pct create 100 local:vztmpl/alpine-3.19-default_20231211_amd64.tar.xz \
  --hostname dns \
  --memory 512 \
  --cores 2 \
  --net0 name=eth0,bridge=vmbr0,ip=dhcp \
  --net1 name=eth1,bridge=vmbr1,ip=10.10.10.2/24 \
  --rootfs local-lvm:8 \
  --unprivileged 1 \
  --features nesting=1 \
  --mp0 /mnt/data/containers/reverse-proxy,mp=/data \
  --start 1

# Enter container and run setup
pct enter 100

# Inside container: run the setup script
wget -O- https://raw.githubusercontent.com/harshsinghmp/dns-reverse-proxy/main/scripts/setup-alpine.sh | sh

βš™οΈ Configuration

Directory Structure (Persistent Storage)

Create this structure on your Proxmox host at /mnt/data/containers/reverse-proxy:

/mnt/data/containers/reverse-proxy/
β”œβ”€β”€ traefik/
β”‚   β”œβ”€β”€ traefik.yml          # Static configuration
β”‚   β”œβ”€β”€ dynamic.yml          # Dynamic routes (your apps!)
β”‚   └── acme.json            # Let's Encrypt certificates (auto-created)
β”œβ”€β”€ cloudflared/
β”‚   β”œβ”€β”€ config.yml           # Tunnel configuration
β”‚   └── credentials.json     # Tunnel credentials (from cloudflared tunnel create)
β”œβ”€β”€ ddns/
β”‚   └── ddns.env             # DDNS-specific environment variables
└── logs/
    β”œβ”€β”€ traefik.log
    └── cloudflared.log

Create the Directory Structure

# On Proxmox host
mkdir -p /mnt/data/containers/reverse-proxy/{traefik,cloudflared,ddns,logs}
chmod 600 /mnt/data/containers/reverse-proxy/traefik/acme.json 2>/dev/null || true
touch /mnt/data/containers/reverse-proxy/traefik/acme.json
chmod 600 /mnt/data/containers/reverse-proxy/traefik/acme.json

Environment Variables (.env)

Copy .env.example to the persistent storage and edit:

cp .env.example /mnt/data/containers/reverse-proxy/.env
nano /mnt/data/containers/reverse-proxy/.env

Required variables:

# Cloudflare API Token (scoped, not Global Key!)
CF_API_TOKEN=your_cloudflare_api_token_here

# Your domain
DOMAIN=example.com

# Email for Let's Encrypt
ACME_EMAIL=admin@example.com

# Cloudflare Zone ID (find in domain overview)
CF_ZONE_ID=your_zone_id_here

# Tunnel name (must match what you created)
TUNNEL_NAME=dns-tunnel

# Subdomains for DDNS updates (comma-separated)
DDNS_DOMAINS=home.example.com,vpn.example.com

# Traefik dashboard (set to false in production)
TRAEFIK_DASHBOARD=true
TRAEFIK_DASHBOARD_USER=admin
# Generate with: htpasswd -nb admin yourpassword
TRAEFIK_DASHBOARD_PASSWORD=$apr1$xxxxx

Cloudflared Tunnel Credentials

  1. Generate tunnel on your local machine:

    # Install cloudflared
    # macOS: brew install cloudflared
    # Linux: See https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/
    
    # Login to Cloudflare
    cloudflared tunnel login
    
    # Create the tunnel
    cloudflared tunnel create dns-tunnel
    
    # This creates ~/.cloudflared/<TUNNEL_ID>.json
  2. Copy credentials to Proxmox:

    scp ~/.cloudflared/*.json root@proxmox:/mnt/data/containers/reverse-proxy/cloudflared/credentials.json
  3. Configure DNS routing in Cloudflare Dashboard:

    • Go to Zero Trust > Access > Tunnels
    • Select your tunnel > Configure
    • Add public hostname: *.example.com β†’ http://localhost:80

πŸ“± Adding Applications

Method 1: Edit dynamic.yml (Recommended)

Edit /mnt/data/containers/reverse-proxy/traefik/dynamic.yml:

# ============================================================
# DYNAMIC CONFIGURATION - ADD YOUR APPS HERE
# ============================================================
# 
# This file is hot-reloaded by Traefik (no restart needed!)
# Add services using internal IPs of your apps
#
# Template for a new service:
#
# routers:
#   myapp:
#     rule: "Host(`myapp.example.com`)"
#     service: myapp
#     entryPoints:
#       - websecure
#     tls:
#       certResolver: cloudflare
#
# services:
#   myapp:
#     loadBalancer:
#       servers:
#         - url: "http://10.10.10.50:8080"
# ============================================================

http:
  routers:
    # ─────────────────────────────────────────
    # Example: Jellyfin Media Server
    # ─────────────────────────────────────────
    jellyfin:
      rule: "Host(`media.example.com`)"
      service: jellyfin
      entryPoints:
        - websecure
      tls:
        certResolver: cloudflare
      middlewares:
        - secure-headers
    
    # ─────────────────────────────────────────
    # Example: Gitea (Self-hosted Git)
    # ─────────────────────────────────────────
    gitea:
      rule: "Host(`git.example.com`)"
      service: gitea
      entryPoints:
        - websecure
      tls:
        certResolver: cloudflare
      middlewares:
        - secure-headers
    
    # ─────────────────────────────────────────
    # Example: Home Assistant
    # ─────────────────────────────────────────
    homeassistant:
      rule: "Host(`home.example.com`)"
      service: homeassistant
      entryPoints:
        - websecure
      tls:
        certResolver: cloudflare
      middlewares:
        - secure-headers
    
    # ─────────────────────────────────────────
    # Example: Proxmox Web UI
    # ─────────────────────────────────────────
    proxmox:
      rule: "Host(`pve.example.com`)"
      service: proxmox
      entryPoints:
        - websecure
      tls:
        certResolver: cloudflare
      middlewares:
        - secure-headers

  services:
    jellyfin:
      loadBalancer:
        servers:
          - url: "http://10.10.10.50:8096"
    
    gitea:
      loadBalancer:
        servers:
          - url: "http://10.10.10.51:3000"
    
    homeassistant:
      loadBalancer:
        servers:
          - url: "http://10.10.10.52:8123"
    
    proxmox:
      loadBalancer:
        servers:
          # Note: Proxmox uses HTTPS internally
          - url: "https://10.10.10.1:8006"
        serversTransport: insecure-skip-verify

  serversTransports:
    insecure-skip-verify:
      insecureSkipVerify: true

  middlewares:
    # Security headers for all services
    secure-headers:
      headers:
        browserXssFilter: true
        contentTypeNosniff: true
        forceSTSHeader: true
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 31536000
        customFrameOptionsValue: "SAMEORIGIN"
        customResponseHeaders:
          X-Robots-Tag: "noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex"
    
    # Basic auth middleware (for protected services)
    auth:
      basicAuth:
        users:
          # Generate: htpasswd -nb admin password
          - "admin:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
    
    # Rate limiting middleware
    rate-limit:
      rateLimit:
        average: 100
        burst: 50

Method 2: Docker Labels (When Running Services in Docker)

If running apps as Docker containers on the same network:

# docker-compose.yml for an app
services:
  myapp:
    image: myapp:latest
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.myapp.rule=Host(`myapp.example.com`)"
      - "traefik.http.routers.myapp.entrypoints=websecure"
      - "traefik.http.routers.myapp.tls.certresolver=cloudflare"
      - "traefik.http.services.myapp.loadbalancer.server.port=8080"
    networks:
      - traefik

🌐 Networking Guide

Recommended Network Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            PROXMOX HOST                                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                          β”‚
β”‚  vmbr0 (WAN Bridge) ──────────────────────────────────────► Internet    β”‚
β”‚     β”‚                                                                    β”‚
β”‚     β”œβ”€β”€ LXC 100 "dns" (eth0: DHCP or static public IP)                  β”‚
β”‚     β”‚                                                                    β”‚
β”‚     └── (Optional) Other public-facing VMs                              β”‚
β”‚                                                                          β”‚
β”‚  vmbr1 (Internal VLAN / Isolated Bridge) ────────────────► Internal     β”‚
β”‚     β”‚                                                                    β”‚
β”‚     β”œβ”€β”€ LXC 100 "dns" (eth1: 10.10.10.2/24)                             β”‚
β”‚     β”œβ”€β”€ LXC 101 "jellyfin" (eth0: 10.10.10.50/24)                       β”‚
β”‚     β”œβ”€β”€ LXC 102 "gitea" (eth0: 10.10.10.51/24)                          β”‚
β”‚     β”œβ”€β”€ VM 103 "docker-host" (eth0: 10.10.10.60/24)                     β”‚
β”‚     └── Other internal services...                                       β”‚
β”‚                                                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Proxmox Network Configuration

Edit /etc/network/interfaces on Proxmox host:

# WAN Bridge (connects to your router/ISP)
auto vmbr0
iface vmbr0 inet static
    address 192.168.1.10/24
    gateway 192.168.1.1
    bridge-ports enp0s25
    bridge-stp off
    bridge-fd 0

# Internal VLAN Bridge (isolated network for apps)
auto vmbr1
iface vmbr1 inet static
    address 10.10.10.1/24
    bridge-ports none
    bridge-stp off
    bridge-fd 0
    # No gateway - this is isolated!
    
# Optional: Enable NAT for internal network to access internet
# (for updates, etc. - containers can reach out but not be reached)
post-up   iptables -t nat -A POSTROUTING -s '10.10.10.0/24' -o vmbr0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '10.10.10.0/24' -o vmbr0 -j MASQUERADE

LXC "dns" Network Configuration

The container has two interfaces:

# /etc/network/interfaces inside the LXC

# WAN interface (for Cloudflared tunnel egress)
auto eth0
iface eth0 inet dhcp
# Or static:
# iface eth0 inet static
#     address 192.168.1.100/24
#     gateway 192.168.1.1

# Internal interface (to reach your apps)
auto eth1
iface eth1 inet static
    address 10.10.10.2/24
    # No gateway on this interface!

Firewall Rules (Proxmox)

For the "dns" LXC, configure these rules in Proxmox Firewall:

# Allow inbound on WAN (if not using Cloudflared exclusively)
# Note: With Cloudflared tunnel, you can block ALL inbound!
[ACCEPT] IN eth0 -p tcp --dport 80
[ACCEPT] IN eth0 -p tcp --dport 443

# Allow all internal traffic from/to apps
[ACCEPT] IN eth1
[ACCEPT] OUT eth1

# Allow outbound for Cloudflared tunnel (uses QUIC/443)
[ACCEPT] OUT eth0 -p tcp --dport 443
[ACCEPT] OUT eth0 -p udp --dport 443

# Block everything else by default
[DROP] IN eth0

Using Cloudflare Tunnel (Zero Open Ports)

With Cloudflared tunnel, you don't need ANY inbound firewall rules:

  1. Cloudflared connects outbound to Cloudflare's edge
  2. Traffic flows: Internet β†’ Cloudflare β†’ Tunnel β†’ Traefik β†’ Internal Apps
  3. No ports exposed on your router or Proxmox

Configure your router:

  • No port forwarding needed!
  • Block all inbound traffic for maximum security

πŸ” Security Checklist

βœ… Cloudflare Token Security

  • Use API Token, NOT Global API Key
  • Scope the token to only required permissions:
    • Zone:Zone:Read (for ACME challenges)
    • Zone:DNS:Edit (for DNS updates)
  • Limit to specific zones (your domain only)
  • Set token expiration if possible
  • Store securely in .env file with chmod 600

βœ… TLS/Certificate Security

  • Use Let's Encrypt production (not staging)
  • Protect acme.json: chmod 600 acme.json
  • Enable HSTS in Traefik middlewares
  • Force TLS 1.2+ in Traefik configuration
  • Enable OCSP stapling (default in Traefik)

βœ… Cloudflared Tunnel Security

  • Store credentials.json securely: chmod 600
  • Run as non-root user inside container
  • Use Access policies for sensitive apps (Cloudflare Zero Trust)
  • Enable tunnel metrics for monitoring

βœ… Container Security

  • Run as unprivileged LXC: --unprivileged 1
  • Enable nesting only if needed: --features nesting=1
  • Minimal packages - Alpine base is already slim
  • No SSH - Use pct enter for console access
  • Read-only rootfs where possible

βœ… Network Security

  • Isolate internal apps on separate VLAN/bridge
  • No port forwarding when using Cloudflared
  • Firewall default deny on WAN interface
  • Internal DNS for service discovery (optional)

βœ… Traefik Security

  • Disable dashboard in production or protect with auth
  • Rate limiting middleware enabled
  • Security headers middleware on all routes
  • Fail2ban integration (optional, advanced)

βœ… Operational Security

  • Regular updates: apk upgrade inside container
  • Monitor logs: /data/logs/*.log
  • Backup credentials: Store copies securely offline
  • Test recovery: Verify you can rebuild from scratch

πŸ” Troubleshooting

Traefik Not Getting Certificates

# Check Traefik logs
tail -f /data/logs/traefik.log

# Verify Cloudflare token
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json"

# Check acme.json permissions
ls -la /data/traefik/acme.json
# Should be: -rw------- (600)

Cloudflared Tunnel Not Connecting

# Check Cloudflared logs
tail -f /data/logs/cloudflared.log

# Test tunnel manually
cloudflared tunnel --config /data/cloudflared/config.yml run

# Verify credentials path
cat /data/cloudflared/config.yml | grep credentials-file
ls -la /data/cloudflared/credentials.json

DDNS Not Updating

# Check DDNS logs
tail -f /data/logs/ddns.log

# Test API manually
curl -X GET "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json"

Container Won't Start

# Check LXC logs on Proxmox host
journalctl -u pve-container@100 -f

# Common issues:
# - Mount point doesn't exist: Create /mnt/data/containers/reverse-proxy
# - Permission issues: Check ownership (should be 100000:100000 for unprivileged)
# - Network bridge missing: Verify vmbr0 and vmbr1 exist

Services Not Reachable

# Inside the LXC, test internal connectivity
ping 10.10.10.50  # Internal app IP
curl http://10.10.10.50:8096  # Test service directly

# Check Traefik router
curl -s http://localhost:8080/api/http/routers | jq

# Verify DNS resolution
nslookup myapp.example.com

πŸ“„ License

MIT License - Feel free to use, modify, and distribute.


πŸ™ Credits

  • Traefik - The Cloud Native Edge Router
  • Cloudflared - Cloudflare Tunnel client
  • Favonia DDNS - Cloudflare DDNS updater
  • Alpine Linux team for the minimal base image

Need help? Open an issue on GitHub or check the Traefik documentation.

About

Proxmox LXC OCI image with Traefik, Cloudflared, and DDNS for homelab reverse proxy

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages