AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Deploy Caddy Reverse Proxy

skill-ichuan-skills-deploy-caddy-reverse-proxy · by ichuan

Deploy Caddy reverse proxy on remote servers with automatic SSL and systemd integration. Use when users want to: (1) Set up reverse proxy for local web services, (2) Configure automatic Let's Encrypt SSL certificates, (3) Set up systemd service with auto-start, (4) Proxy HTTP/WebSocket traffic. Triggered by phrases like 'deploy caddy', 'setup reverse proxy', 'configure caddy', 'caddy ssl'.

No reviews yet
0 installs
34 views
0.0% view→install

Install

$ agentstack add skill-ichuan-skills-deploy-caddy-reverse-proxy

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-ichuan-skills-deploy-caddy-reverse-proxy)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Deploy Caddy Reverse Proxy? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Deploy Caddy Reverse Proxy

Overview

Automatically deploy Caddy reverse proxy server on remote servers with:

  • Automatic SSL Management: Let's Encrypt certificate acquisition and renewal
  • Reverse Proxy Configuration: Route domain traffic to local services (HTTP/WebSocket)
  • Systemd Integration: Auto-start and crash recovery
  • Smart Environment Detection: Automatic system detection and optimal configuration

Prerequisites

Verify before deployment:

  1. Server Access:
  • SSH access configured (supports SSH config aliases)
  • sudo privileges
  • Internet access (for downloading Caddy and obtaining certificates)
  1. DNS Configuration:
  • Domain points to server IP (A record or CNAME)
  • DNS must be propagated before SSL certificate can be obtained
  1. Local Service:
  • Web service already running on server
  • Listening on 127.0.0.1 or localhost (note the port number)

Workflow

1. Parameter Collection

Use AskUserQuestion tool to interactively collect deployment parameters:

**Required Parameters**:
- SSH host alias or address (e.g., `dev` or `user@example.com`)
- Domain name (e.g., `app.example.com`)
- Backend service port (e.g., `8000`, `3000`)

**Optional Parameters**:
- Whether static file serving is needed (if frontend is bundled separately)
- Static file path (e.g., `/var/www/app/dist`)
- Routing rules (e.g., `/api` proxies to port A, `/ui` serves static files)

Example Questions:

question: "How do you connect to the server?"
options:
  - label: "SSH config alias (Recommended)"
    description: "Use host alias from ~/.ssh/config, e.g., 'dev'"
  - label: "Full SSH address"
    description: "Format: user@hostname or user@ip"

question: "What is the domain name?"
header: "Domain"

question: "What port is the backend service listening on?"
header: "Backend Port"

2. Environment Detection

Connect to server and perform environment checks:

# Check if Caddy is installed
which caddy && caddy version

# Check CPU architecture (for downloading correct binary)
uname -m  # x86_64 → amd64, aarch64 → arm64

# Check operating system
cat /etc/os-release

# Check available users (prefer www-data, create caddy user if not exists)
id www-data 2>/dev/null || id caddy 2>/dev/null

# Check if backend service is running
sudo ss -tlnp | grep 

Adaptive Strategy:

  • If Caddy is installed and version >= 2.0, ask whether to reinstall or use existing version
  • If www-data user exists, use it; otherwise create caddy system user
  • If backend service is not running, warn user and ask whether to continue

3. Install Caddy

If Caddy is not installed or needs update:

# Download Caddy binary
cd /tmp
curl -L "https://caddyserver.com/api/download?os=linux&arch=" -o caddy
chmod +x caddy

# Install to system path
sudo mv caddy /usr/bin/caddy

# Verify installation
/usr/bin/caddy version

Architecture Mapping:

  • x86_64amd64
  • aarch64arm64
  • armv7larmv7

4. Create Necessary Directories and Users

# If using www-data user (Debian/Ubuntu default)
sudo mkdir -p /etc/caddy /var/lib/caddy
sudo chown -R www-data:www-data /etc/caddy /var/lib/caddy

# If need to create caddy user (CentOS/RHEL/others)
sudo groupadd --system caddy
sudo useradd --system --gid caddy \
  --create-home --home-dir /var/lib/caddy \
  --shell /sbin/nologin \
  --comment "Caddy web server" caddy

5. Generate Configuration Files

5.1 Caddyfile

Generate configuration based on user parameters:

Scenario A: Pure Reverse Proxy (Most Common)

example.com {
    reverse_proxy http://127.0.0.1:8000

    log {
        output stdout
    }
}

Scenario B: Static Files + API Proxy

example.com {
    # Static file serving
    handle /ui/* {
        root * /var/www/app/dist
        try_files {path} /index.html
        file_server
    }

    # API reverse proxy
    handle /api/* {
        reverse_proxy http://127.0.0.1:8000
    }

    log {
        output stdout
    }
}

Scenario C: Multi-Service Proxy

example.com {
    # Main application
    handle /app/* {
        reverse_proxy http://127.0.0.1:3000
    }

    # Backend API
    handle /api/* {
        reverse_proxy http://127.0.0.1:8000
    }

    # WebSocket service
    handle /ws {
        reverse_proxy http://127.0.0.1:9000
    }

    # Default route
    handle {
        reverse_proxy http://127.0.0.1:3000
    }

    log {
        output stdout
    }
}

Write configuration file:

sudo tee /etc/caddy/Caddyfile > /dev/null 
EOF

# Validate configuration syntax
sudo /usr/bin/caddy validate --config /etc/caddy/Caddyfile
5.2 Systemd Service File

Generate service file using assets/caddy.service.template:

sudo tee /etc/systemd/system/caddy.service > /dev/null 
# Ensure backend service is running

# 3. Check certificate acquisition logs
sudo journalctl -u caddy -n 30 --no-pager | grep -E 'certificate obtained|error'
# Expected output: certificate obtained successfully

# 4. Test HTTPS access
curl -I https:// -m 10
# Expected output: HTTP/2 200

8. Generate Deployment Report

Show deployment results to user:

## ✅ Caddy Deployment Complete

### Deployment Configuration
- **Domain**: 
- **Backend Service**: 127.0.0.1: ✅ Running
- **SSL Certificate**: Let's Encrypt (automatically obtained)
- **Protocol Support**: HTTP/2, HTTP/3, WebSocket

### Service Status
- Caddy Version: 
- Listening Ports: 80 (HTTP → HTTPS), 443 (HTTPS), 2019 (admin)
- Running User: 
- Auto-start: Enabled

### Key File Locations
- Configuration: `/etc/caddy/Caddyfile`
- Service File: `/etc/systemd/system/caddy.service`
- Certificate Storage: `/var/lib/caddy/`
- Binary: `/usr/bin/caddy`

### Common Commands
```bash
# Check service status
sudo systemctl status caddy

# View live logs
sudo journalctl -u caddy -f

# Reload configuration (zero-downtime)
sudo systemctl reload caddy

# Restart service
sudo systemctl restart caddy

# Validate configuration syntax
sudo caddy validate --config /etc/caddy/Caddyfile

Test Results

✅ HTTPS access working ✅ SSL certificate obtained successfully ✅ Reverse proxy working correctly

Your service is now accessible at https://!


## Troubleshooting

### Common Issues

#### 1. Certificate Acquisition Failure

**Error**: `storage is probably misconfigured` or `permission denied`

**Cause**: Caddy cannot write to certificate storage directory

**Solution**:

```bash
# Check environment variable configuration
sudo systemctl cat caddy | grep Environment
# Should include: Environment=XDG_DATA_HOME=/var/lib/caddy

# Check directory permissions
ls -ld /var/lib/caddy
# Should be: drwxr-xr-x www-data www-data

# Fix permissions
sudo chown -R www-data:www-data /var/lib/caddy
sudo systemctl restart caddy
2. Port Binding Failure

Error: bind: permission denied or address already in use

Cause:

  • No permission to bind ports 80/443
  • Port already in use by another service

Solution:

# Check capabilities
sudo systemctl cat caddy | grep AmbientCapabilities
# Should include: AmbientCapabilities=CAP_NET_BIND_SERVICE

# Check port usage
sudo ss -tlnp | grep :443
# If occupied by another program, stop it or modify Caddyfile to use different port

# If system doesn't support AmbientCapabilities, manually grant permission
sudo setcap 'cap_net_bind_service=+ep' /usr/bin/caddy
3. DNS Resolution Failure

Error: no such host or DNS problem: NXDOMAIN

Cause: Domain not correctly pointing to server IP

Solution:

# Check DNS record
dig +short 
# Should return server public IP

# Check server public IP
curl -4 ifconfig.me

# If DNS not propagated, wait for TTL to expire (usually 5 minutes to 1 hour)
4. Reverse Proxy 502 Error

Error: Accessing domain returns 502 Bad Gateway

Cause: Backend service not running or incorrect listening address

Solution:

# Check backend service status
sudo ss -tlnp | grep 

# Test local access
curl http://127.0.0.1:

# Check Caddy logs
sudo journalctl -u caddy -f

# If backend service listens on 0.0.0.0 instead of 127.0.0.1, modify Caddyfile
5. WebSocket Connection Failure

Error: WebSocket handshake fails or connection interrupted

Cause: Caddy 2.x supports WebSocket by default, usually a backend issue

Solution:

# Check backend service WebSocket endpoint
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: test" \
  http://127.0.0.1:/ws

# If special configuration needed, add to Caddyfile:
handle /ws {
    reverse_proxy http://127.0.0.1: {
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }
}

Advanced Configuration

Multi-Domain Configuration

app.example.com {
    reverse_proxy http://127.0.0.1:8000
}

api.example.com {
    reverse_proxy http://127.0.0.1:9000
}

Custom SSL Certificate Email

{
    email admin@example.com
}

example.com {
    reverse_proxy http://127.0.0.1:8000
}

Add Security Headers

example.com {
    reverse_proxy http://127.0.0.1:8000

    header {
        # HSTS
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        # Prevent XSS
        X-Content-Type-Options "nosniff"
        # Prevent clickjacking
        X-Frame-Options "DENY"
        # CSP
        Content-Security-Policy "default-src 'self'"
    }
}

Enable Access Log Files

example.com {
    reverse_proxy http://127.0.0.1:8000

    log {
        output file /var/log/caddy/access.log {
            roll_size 100mb
            roll_keep 10
        }
    }
}

Rate Limiting Configuration

example.com {
    rate_limit {
        zone dynamic {
            key {remote_host}
            events 100
            window 1m
        }
    }

    reverse_proxy http://127.0.0.1:8000
}

Resources

Templates

  • assets/Caddyfile.template - Caddyfile configuration template
  • assets/caddy.service.template - systemd service unit file template

Documentation

Maintenance

View Certificate Information
# View certificate storage location
ls -la /var/lib/caddy/caddy/certificates/

# View certificate details
sudo /usr/bin/caddy list-certificates
Force Certificate Renewal
# Caddy renews automatically, but to manually trigger:
sudo systemctl reload caddy
Update Caddy
# Download new version
cd /tmp
curl -L "https://caddyserver.com/api/download?os=linux&arch=amd64" -o caddy
chmod +x caddy

# Replace old version
sudo systemctl stop caddy
sudo mv caddy /usr/bin/caddy
sudo systemctl start caddy

# Verify version
caddy version
Migrate Configuration
# Backup configuration
sudo tar -czf caddy-backup-$(date +%Y%m%d).tar.gz \
  /etc/caddy /var/lib/caddy /etc/systemd/system/caddy.service

# Restore configuration
sudo tar -xzf caddy-backup-YYYYMMDD.tar.gz -C /
sudo systemctl daemon-reload
sudo systemctl restart caddy

Best Practices

  1. Verify DNS Before Deployment: Ensure domain resolves to server IP
  2. Use Environment Variables: systemd service file must set XDG_DATA_HOME
  3. Principle of Least Privilege: Use www-data or caddy system user, avoid root
  4. Monitor Logs: Watch logs for 5-10 minutes after first deployment to ensure certificate acquisition
  5. Backup Certificates: Certificates stored in /var/lib/caddy, backup regularly
  6. Test Restart: After deployment, run sudo reboot to verify auto-start works
  7. Firewall Configuration: Ensure ports 80/443 are open (cloud servers need security group configuration)

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.