--- title: Setting Up a Reverse Proxy description: "How to use Caddy, Nginx Proxy Manager, or Traefik to give your self-hosted tools proper domains and automatic SSL." --- import { Tabs } from 'nextra/components' # Setting Up a Reverse Proxy Right now your tools are running on ports like `:3001` or `:8080`. A **reverse proxy** is the traffic cop that maps a domain like `uptime.yourdomain.com` to your server's local port and handles SSL automatically. ## Which one should I pick? - **Caddy:** Best for 99% of people. Zero-config SSL, human-readable config, extremely fast. - **Nginx Proxy Manager:** Best if you want a web UI to click and manage your domains. - **Traefik:** Best if you want a "hands-off" approach that auto-discovers new containers as you spin them up (complex but powerful). --- ### Caddy Setup Caddy is the "batteries included" proxy. It just works. #### 1. The Docker Compose Create a folder for Caddy and add this `docker-compose.yml`: ```yaml version: '3.8' services: caddy: image: caddy:2-alpine restart: unless-stopped ports: - "80:80" - "443:443" - "443:443/udp" volumes: - ./Caddyfile:/etc/caddy/Caddyfile - caddy_data:/data - caddy_config:/config volumes: caddy_data: caddy_config: ``` #### 2. The Caddyfile In the same folder, create a file named `Caddyfile`: ```caddy uptime.yourdomain.com { reverse_proxy localhost:3001 } plausible.yourdomain.com { reverse_proxy localhost:8000 } ``` #### 3. Start it ```bash docker compose up -d ``` ### Nginx Proxy Manager (NPM) Setup NPM gives you a beautiful web interface to manage your SSL and proxy hosts. #### 1. The Docker Compose ```yaml version: '3.8' services: app: image: 'jc21/nginx-proxy-manager:latest' restart: unless-stopped ports: - '80:80' - '81:81' - '443:443' volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt ``` #### 2. Access the UI 1. Visit `http://your-server-ip:81` 2. Default credentials: - Email: `admin@example.com` - Password: `changeme` 3. Change your login info immediately. 4. Click **Proxy Hosts** -> **Add Proxy Host** to point your domain to your tool's port. ### Traefik Setup Traefik uses "labels" on your other containers to automatically route traffic. #### 1. The Traefik Container ```yaml version: '3.8' services: traefik: image: traefik:v3.0 command: - "--api.insecure=true" - "--providers.docker=true" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.myresolver.acme.tlschallenge=true" - "--certificatesresolvers.myresolver.acme.email=your-email@example.com" - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" ports: - "80:80" - "443:443" - "8080:8080" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" - "./letsencrypt:/letsencrypt" ``` #### 2. Routing a container Add these labels to any *other* container you want to proxy: ```yaml labels: - "traefik.enable=true" - "traefik.http.routers.mytool.rule=Host(`mytool.yourdomain.com`)" - "traefik.http.routers.mytool.entrypoints=websecure" - "traefik.http.routers.mytool.tls.certresolver=myresolver" ``` --- ## 🔒 A Note on SSL/TLS Every proxy above handles SSL certificates via **Let's Encrypt** automatically. **Crucial Step:** Before you start your proxy, your domain's **DNS A Record** must point to your server's public IP address. If the DNS isn't pointing correctly, Let's Encrypt will fail to issue a certificate. ## Next Steps → [Your First Deployment](/quick-start/first-deployment) — Connect your tools to your new proxy. → [SSL/TLS Deep Dive](/concepts/ssl-tls) — How it works under the hood.