Claude-skill-registry caddy-subdomain-add
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/caddy-subdomain-add" ~/.claude/skills/majiayu000-claude-skill-registry-caddy-subdomain-add && rm -rf "$T"
skills/data/caddy-subdomain-add/SKILL.mdAdd Subdomain Skill
Interactive guide for adding new subdomains to the network infrastructure.
Quick Start
Minimal Request: "Add grafana running on port 3001"
Full Request Example:
Add a new subdomain: - Name: Grafana Dashboard - Subdomain: grafana - Backend: 192.168.68.135:3001 - HTTPS: yes - Auth: yes
Result: Service accessible at https://grafana.temet.ai with Google OAuth protection.
Table of Contents
- When to Use This Skill
- What This Skill Does
- Instructions
- 3.1 Gather Service Information
- 3.2 Validate Input
- 3.3 Determine Configuration
- 3.4 Add to domains.toml
- 3.5 Apply Changes
- 3.6 Manual Tunnel Step
- 3.7 Verify Setup
- Supporting Files
- Expected Outcomes
- Integration Points
- Expected Benefits
- Requirements
- Red Flags to Avoid
When to Use This Skill
Explicit Triggers:
- "Add a subdomain for [service]"
- "Create subdomain [name]"
- "Add [service] to the network"
- "Set up reverse proxy for [service]"
- "Expose [service] externally"
Implicit Triggers:
- Setting up a new Docker container that needs external access
- Installing new software that requires HTTPS
- Configuring a new IoT device for remote access
Debugging Triggers:
- "Why can't I access [service].temet.ai?"
- "How do I add HTTPS to my service?"
What This Skill Does
- Gathers Information - Asks interactive questions about the service
- Validates Input - Checks subdomain format, IP addresses, ports
- Suggests Defaults - Recommends settings based on service type
- Configures domains.toml - Adds service entry with correct options
- Applies Changes - Runs manage-domains.sh to generate configs
- Provides Tunnel Instructions - Guides user through manual Cloudflare step
- Verifies Setup - Tests DNS, HTTPS, and authentication
Instructions
3.1 Gather Service Information
Ask the user for the following details (provide examples):
Required:
| Field | Question | Example |
|---|---|---|
| name | What is the display name for this service? | "Grafana Dashboard" |
| subdomain | What subdomain do you want? (without .temet.ai) | "grafana" |
| backend | Where is the service running? (IP:port or container:port) | "192.168.68.135:3001" or "grafana:3000" |
Service Type (for intelligent defaults):
| Type | Description |
|---|---|
| web | Standard web application (default settings) |
| docker | Docker container on the same network |
| iot | IoT device (needs header stripping) |
| api | API service (may need custom headers) |
| external | Service on different machine on LAN |
3.2 Validate Input
Use the validation script to check subdomain and backend:
python3 .claude/skills/add-subdomain/scripts/validate-subdomain.py grafana 192.168.68.135:3001
Rules:
- Subdomain: lowercase alphanumeric + hyphens, max 63 chars, no leading/trailing hyphens
- Backend: IP:port (e.g.,
) or container:port (e.g.,192.168.68.135:3001
)grafana:3000 - Check for duplicates before adding
3.3 Determine Configuration
Use service type to select defaults (see
references/reference.md for full matrix):
| Type | enable_https | enable_http | require_auth | Special |
|---|---|---|---|---|
| web | true | false | true | proxy_headers |
| docker | true | false | true | container:port backend |
| iot | false | true | true | strip_cf_headers |
| external | true | false | true | LAN IP backend |
| self-signed | true | false | true | tls_insecure |
| public | false | true | false | no auth |
3.4 Add to domains.toml
Location:
/home/dawiddutoit/projects/network/domains.toml
Steps:
- Read current domains.toml
- Find appropriate section (Core Infrastructure, IoT Devices, or Utility Services)
- Append new service entry before the Advanced Configuration section
- Use Edit tool to add the entry
Template:
[[services]] name = "{name}" subdomain = "{subdomain}" backend = "{backend}" enable_https = {enable_https} enable_http = {enable_http} dns_ip = "{dns_ip}" require_auth = {require_auth} {optional_fields}
3.5 Apply Changes
Run the management script:
cd /home/dawiddutoit/projects/network && ./scripts/manage-domains.sh apply
Expected output:
=== Applying Domain Configuration === Validating configuration... [checkmark] Configuration is valid Generating Caddyfile... [checkmark] Caddyfile generated successfully Updating Pi-hole DNS entries... [checkmark] Pi-hole DNS entries updated Syncing Cloudflare Access applications... [checkmark] Cloudflare Access synced successfully Reloading Caddy configuration... [checkmark] Caddy reloaded successfully Restarting Pi-hole to apply DNS changes... [checkmark] Pi-hole restarted successfully
3.6 Manual Tunnel Step
Provide clear instructions for the Cloudflare Tunnel configuration:
MANUAL STEP REQUIRED: Add Cloudflare Tunnel Route 1. Go to: https://one.dash.cloudflare.com 2. Navigate to: Access -> Tunnels 3. Click on tunnel: "pi-home" (or your tunnel name) 4. Click "Configure" -> "Public Hostname" -> "Add a public hostname" 5. Enter: - Subdomain: {subdomain} - Domain: temet.ai - Type: {HTTP or HTTPS} - URL: {backend_for_tunnel} For HTTPS services: https://caddy:443 For HTTP-only services: http://caddy:80 or direct to service 6. Click "Save hostname"
Tunnel Backend Selection:
| Service Type | Tunnel URL |
|---|---|
| HTTPS enabled | |
| HTTP only (IoT) | Direct to service: |
| Docker container | or |
3.7 Verify Setup
After tunnel configuration, run verification:
1. DNS Resolution (local):
dig @192.168.68.135 {subdomain}.temet.ai +short
Expected: Returns the dns_ip configured
2. HTTPS Certificate:
echo | openssl s_client -servername {subdomain}.temet.ai \ -connect {subdomain}.temet.ai:443 2>/dev/null | \ openssl x509 -noout -dates -issuer
Expected: Valid certificate from Let's Encrypt
3. HTTP Response:
curl -I https://{subdomain}.temet.ai
Expected: HTTP/2 200 or 302 (redirect to login)
4. Service List:
./scripts/manage-domains.sh list
Expected: New service appears in list
Supporting Files
| File | Purpose |
|---|---|
| Complete configuration options reference |
| Common service configuration examples |
| Pre-validation of subdomain and backend |
Validation Script Usage:
python3 .claude/skills/add-subdomain/scripts/validate-subdomain.py grafana 192.168.68.135:3001
Expected Outcomes
Success:
- Service entry added to domains.toml
- Caddyfile regenerated with new service block
- Pi-hole DNS entry created
- Cloudflare Access application created (if require_auth=true)
- Caddy reloaded with new certificate
- Service accessible at https://{subdomain}.temet.ai
Partial Success:
- Configuration applied but tunnel not configured (user reminder provided)
- Certificate pending (may take 1-2 minutes)
Failure Indicators:
- domains.toml syntax error -> validate and fix
- Caddy reload failed -> check Caddyfile syntax
- DNS not resolving -> check Pi-hole logs
- Certificate error -> check Cloudflare API token
Integration Points
This skill integrates with:
| Component | Purpose |
|---|---|
| Central configuration source |
| Applies configuration changes |
| Generates Caddyfile from domains.toml |
| Updates Pi-hole DNS entries |
| Creates/updates Access applications |
| Cloudflare Tunnel | Manual public hostname configuration |
Related Skills:
- For adding new top-level domainssetup-new-domain-services
- For certificate issuestroubleshoot-ssl-certificates
- For authentication problemsdiagnose-cloudflare-access
Expected Benefits
| Metric | Before | After |
|---|---|---|
| Time to add service | 15-30 min (manual) | 2-5 min (guided) |
| Configuration errors | Common (manual editing) | Rare (validated) |
| Documentation needed | Multiple files | Single skill reference |
| Consistency | Variable | Standardized |
Requirements
Environment:
- Docker running with caddy, pihole containers
- Cloudflare tunnel connected
- Valid
with API tokens.env
Tools needed:
- Read, Write, Edit (for domains.toml)
- Bash (for apply script and verification)
- Grep (for duplicate checking)
Red Flags to Avoid
- Do not add duplicate subdomains (check first)
- Do not use uppercase in subdomain names
- Do not forget the manual tunnel step
- Do not skip verification after apply
- Do not use
on Linux (use actual IP)host.docker.internal - Do not enable both HTTPS and HTTP unless specifically needed
- Do not set require_auth=false unless service must be public
- Do not skip tls_insecure for services with self-signed certs
Notes
- The Pi IP is typically
for services running on the Pi192.168.68.135 - IoT devices need
to work properlystrip_cf_headers = true - Services with self-signed certs need
tls_insecure = true - Root redirects (like
) use/admin/
optionroot_redirect - The tunnel step is manual because Cloudflare API for tunnels is complex
- Always run
to see current services./scripts/manage-domains.sh list