Skip to main content

Caddy Integration

OnTree seamlessly integrates with Caddy to provide automatic HTTPS certificates and easy domain management for your applications. This allows you to expose your apps securely at custom domains like https://app.yourdomain.com.

How It Works

OnTree uses Caddy's Admin API to dynamically configure reverse proxy routes:

  1. You request a subdomain for your app
  2. OnTree configures Caddy with the routing rules
  3. Caddy obtains HTTPS certificates automatically
  4. Your app becomes accessible at the custom domain

Setting Up Integration

Prerequisites

Before using domain features:

  1. Caddy installed with admin API enabled
  2. Domain configured (public or Tailscale)
  3. DNS pointed to your server
  4. Ports 80 & 443 accessible

Quick Setup

  1. Install Caddy (see Domain Setup)
  2. Configure domains in OnTree:
    PUBLIC_BASE_DOMAIN=example.com treeos
  3. Verify integration - Check app detail pages for Domain & Access section

Using Domain Management

Exposing an App

  1. Navigate to your app in OnTree
  2. Find Domain & Access section
  3. Enter subdomain (e.g., chat, wiki, cloud)
  4. Click "Expose App"

OnTree will:

  • Configure Caddy reverse proxy
  • Set up HTTPS automatically
  • Make app available immediately

Subdomain Guidelines

Choose subdomains wisely:

  • Descriptive: photos not app1
  • Short: wiki not my-personal-wikipedia
  • Valid: Lowercase letters, numbers, hyphens
  • Unique: Each subdomain used once

Managing Exposed Apps

For exposed apps, you can:

  • View URLs - See all access methods
  • Check status - Verify subdomain availability
  • Unexpose - Remove public access
  • Change subdomain - Unexpose and re-expose

Domain Types

Public Domains

For internet-accessible applications:

public_base_domain = "example.com"

Features:

  • Accessible from anywhere
  • Automatic Let's Encrypt certificates
  • Perfect for public services

Tailscale Domains

For private, secure access:

tailscale_base_domain = "machine.tail-scale.ts.net"

Features:

  • Only accessible within Tailnet
  • Built-in authentication
  • Ideal for internal tools

Using Both

Configure both for flexibility:

public_base_domain = "example.com"
tailscale_base_domain = "machine.tail-scale.ts.net"

Choose per-app whether to use public or private domain.

Advanced Configuration

Custom Headers

Add security headers via Caddy:

app.example.com {
reverse_proxy localhost:3000 {
header_up X-Real-IP {remote_host}
header_up X-Forwarded-Proto {scheme}
}

header {
Strict-Transport-Security "max-age=31536000"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
}
}

Path-Based Routing

Expose apps at paths instead of subdomains:

example.com/app1 -> localhost:3001
example.com/app2 -> localhost:3002

(Configuration coming soon)

Wildcard Certificates

Caddy automatically handles wildcard certificates:

  • Single certificate for *.example.com
  • Covers all subdomains
  • Automatic renewal

Security Features

Automatic HTTPS

All exposed apps get:

  • SSL/TLS encryption - Data in transit protected
  • HTTP → HTTPS redirect - Force secure connections
  • Modern cipher suites - Strong encryption
  • Certificate renewal - Automatic before expiry

Access Control

Implement access restrictions:

Basic Authentication

app.example.com {
basicauth {
admin $2a$14$Zkx19XV...
}
reverse_proxy localhost:3000
}

IP Whitelisting

app.example.com {
@allowed {
remote_ip 192.168.1.0/24 10.0.0.0/8
}
handle @allowed {
reverse_proxy localhost:3000
}
respond "Access denied" 403
}

Rate Limiting

Protect against abuse:

app.example.com {
rate_limit {
zone dynamic 100r/m
}
reverse_proxy localhost:3000
}

Troubleshooting

Common Issues

"Caddy is not available"

  1. Check Caddy is running:

    systemctl status caddy
  2. Verify admin API:

    curl http://localhost:2019/config/
  3. Check firewall allows localhost:2019

Certificate Errors

  1. Check DNS propagation:

    dig subdomain.example.com
  2. Verify ports 80/443 are open:

    sudo ufw status
  3. Check Caddy logs:

    journalctl -u caddy -f

Subdomain Not Working

  1. Verify DNS wildcard record exists
  2. Check subdomain doesn't conflict
  3. Test direct access to app port
  4. Review OnTree logs for errors

Debug Mode

Enable detailed logging:

# OnTree config
debug = true
caddy_debug = true

Check logs for:

  • Caddy API requests
  • Response details
  • Configuration sent

Best Practices

Domain Organization

Structure your subdomains:

  • By function: api, admin, public
  • By environment: dev-, staging-, prod-
  • By project: project1-, project2-

Security Hardening

  1. Use strong subdomains - Avoid common names
  2. Enable monitoring - Watch for unusual traffic
  3. Regular updates - Keep Caddy current
  4. Backup configurations - Save Caddy config

Performance

Optimize for speed:

  1. Enable HTTP/2 - Caddy does this automatically
  2. Configure compression - Reduce bandwidth
  3. Set cache headers - Improve load times
  4. Use CDN - For static assets

Integration Examples

WordPress with Custom Domain

  1. Deploy WordPress from template
  2. Expose at blog.example.com
  3. Update WordPress settings:
    • WordPress Address: https://blog.example.com
    • Site Address: https://blog.example.com

Nextcloud with Tailscale

  1. Deploy Nextcloud
  2. Expose on Tailscale domain
  3. Access securely from anywhere via Tailnet
  4. No public internet exposure

Development Environment

  1. Deploy code-server
  2. Expose at dev.example.com
  3. Add basic auth for security
  4. Access VS Code from any browser

Future Enhancements

Planned Caddy integration features:

  • Load balancing - Multiple container backends
  • Health checks - Automatic failover
  • WebSocket support - For real-time apps
  • Custom middleware - Extended functionality
  • Multi-domain - Different domains per app
  • Certificate management UI - View/manage certs

The Caddy integration transforms OnTree from a local container manager into a full-featured hosting platform with enterprise-grade security and convenience.