Caddy SSL Certificate Generation and API Sync

Overview

The dodev dashboard includes a Caddy management interface that allows configuration of reverse proxy routes and automatic SSL certificate generation through the Caddy API.

Key Components

1. Caddy Server Setup (10.3.3.3)

  • Location: /root/local/caddy on the server
  • Docker-based deployment using docker-compose.yml
  • Configured for Let's Encrypt SSL with Cloudflare DNS challenge
  • Admin API exposed on port 2019

2. Required Environment Variables

The server requires these environment variables in .env:

CLOUDFLARE_API_TOKEN=your_token_here  # For DNS challenge
ACME_EMAIL=email@domain.com          # For Let's Encrypt
CADDY_ADMIN_KEY=your_api_key         # For API authentication
CADDY_LOG_LEVEL=INFO                 # Logging level

3. API Integration

  • Endpoint: /api/caddy/sync in dodev
  • Client: CaddyClient class in /lib/caddy-client.ts
  • Function: Pushes route configurations from the dashboard to Caddy via API

How SSL Certificate Generation Works

  1. Route Configuration: When you add routes in the Caddy dashboard (e.g., dns.local.dev → 10.3.3.3:5380)

  2. Sync Process: Clicking "Sync to Caddy" calls the API which:

    • Builds a Caddy configuration with route definitions
    • Extracts hostnames and creates TLS automation policies
    • Includes Cloudflare API token for DNS challenge
    • Pushes configuration to Caddy via Admin API
  3. Certificate Generation: Caddy automatically:

    • Detects domains needing certificates
    • Uses Cloudflare DNS challenge to verify ownership
    • Requests Let's Encrypt certificates
    • Serves HTTPS automatically

Common Issues and Solutions

Issue: No SSL Certificates Generated

Root Cause: Despite proper ACME setup, if no domain configurations are loaded into Caddy, it won't request certificates.

Diagnosis:

# Check current Caddy configuration
curl http://10.3.3.3:2019/config/ | jq .

# Look for empty routes in servers.srv0.routes

Solution:

  1. Ensure routes are configured in the dashboard
  2. Click "Sync to Caddy" to push configuration
  3. Verify sync completes successfully
  4. Check Caddy logs: docker logs caddy-reverse-proxy

Issue: Sync Button Does Nothing

Possible Causes:

  1. Missing Caddy API URL in settings
  2. Incorrect API key
  3. Network connectivity issues
  4. Cloudflare token not configured in settings

Solution:

  1. Go to Settings tab in Caddy dashboard
  2. Configure:
    • Caddy API URL: http://10.3.3.3:2019
    • Caddy API Key: (from server's .env file)
    • Cloudflare API Token: (for DNS challenge)
  3. Test connection
  4. Retry sync

Configuration Files

Server Caddyfile Structure

{
    admin 0.0.0.0:2019
    email {$ACME_EMAIL}
    acme_dns cloudflare {$CLOUDFLARE_API_TOKEN}
}

# Domain configurations loaded via API
import /config/*.caddy

API Configuration Format

The sync API converts dashboard routes to Caddy format:

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "listen": [":443"],
          "routes": [/* domain routes */]
        }
      }
    },
    "tls": {
      "automation": {
        "policies": [/* TLS policies with Cloudflare DNS */]
      }
    }
  }
}

Verification Steps

  1. Check API Connection:

    curl http://10.3.3.3:2019/config/
  2. Verify Routes Loaded:

    curl http://10.3.3.3:2019/config/apps/http/servers/srv0/routes | jq .
  3. Monitor Certificate Generation:

    docker logs -f caddy-reverse-proxy
  4. Test HTTPS:

    curl -I https://your-domain.com

Important Notes

  • The Caddy API requires authentication if CADDY_ADMIN_KEY is set
  • Cloudflare API token needs Zone:DNS:Edit permissions
  • For .local.dev domains, ensure DNS points to 10.3.3.3
  • Certificate generation may take a few minutes on first request
  • Caddy caches certificates in the caddy_data Docker volume

On this page