caddy-subdomain-add
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAdd Subdomain Skill
Add 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: yesResult: Service accessible at https://grafana.temet.ai with Google OAuth protection.
最简请求: "Add grafana running on port 3001"
完整请求示例:
Add a new subdomain:
- Name: Grafana Dashboard
- Subdomain: grafana
- Backend: 192.168.68.135:3001
- HTTPS: yes
- Auth: yes结果: 服务可通过https://grafana.temet.ai访问,并受Google OAuth保护。
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
何时使用此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?"
明确触发指令:
- "Add a subdomain for [service]"
- "Create subdomain [name]"
- "Add [service] to the network"
- "Set up reverse proxy for [service]"
- "Expose [service] externally"
隐含触发场景:
- 配置需要外部访问的新Docker容器
- 安装需要HTTPS的新软件
- 配置用于远程访问的新IoT设备
调试触发指令:
- "Why can't I access [service].temet.ai?"
- "How do I add HTTPS to my service?"
What This Skill Does
该Skill的功能
- 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
- 收集信息 - 通过交互式提问获取服务相关详情
- 验证输入 - 检查子域名格式、IP地址和端口
- 建议默认值 - 根据服务类型推荐设置
- 配置domains.toml - 添加包含正确选项的服务条目
- 应用更改 - 运行manage-domains.sh生成配置
- 提供隧道配置说明 - 引导用户完成Cloudflare手动步骤
- 验证设置 - 测试DNS、HTTPS和认证
Instructions
操作步骤
3.1 Gather Service Information
3.1 收集服务信息
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 |
向用户询问以下详情(提供示例):
必填项:
| 字段 | 问题 | 示例 |
|---|---|---|
| name | 该服务的显示名称是什么? | "Grafana Dashboard" |
| subdomain | 你想要的子域名是什么?(不含.temet.ai) | "grafana" |
| backend | 服务运行在何处?(IP:端口 或 容器:端口) | "192.168.68.135:3001" 或 "grafana:3000" |
服务类型(用于智能默认值):
| 类型 | 描述 |
|---|---|
| web | 标准Web应用(默认设置) |
| docker | 同一网络中的Docker容器 |
| iot | IoT设备(需要剥离请求头) |
| api | API服务(可能需要自定义请求头) |
| external | 局域网中另一台机器上的服务 |
3.2 Validate Input
3.2 验证输入
Use the validation script to check subdomain and backend:
bash
python3 .claude/skills/add-subdomain/scripts/validate-subdomain.py grafana 192.168.68.135:3001Rules:
- 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
使用验证脚本检查子域名和后端地址:
bash
python3 .claude/skills/add-subdomain/scripts/validate-subdomain.py grafana 192.168.68.135:3001规则:
- 子域名:小写字母、数字和连字符,最多63个字符,首尾不能为连字符
- 后端地址:IP:端口(例如 )或容器:端口(例如
192.168.68.135:3001)grafana:3000 - 添加前检查是否存在重复
3.3 Determine Configuration
3.3 确定配置
Use service type to select defaults (see for full matrix):
references/reference.md| 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 |
根据服务类型选择默认值(完整配置矩阵请参考):
references/reference.md| 类型 | enable_https | enable_http | require_auth | 特殊设置 |
|---|---|---|---|---|
| web | true | false | true | proxy_headers |
| docker | true | false | true | container:port后端 |
| iot | false | true | true | strip_cf_headers |
| external | true | false | true | LAN IP后端 |
| self-signed | true | false | true | tls_insecure |
| public | false | true | false | 无认证 |
3.4 Add to domains.toml
3.4 添加到domains.toml
Location:
/home/dawiddutoit/projects/network/domains.tomlSteps:
- 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:
toml
[[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}位置:
/home/dawiddutoit/projects/network/domains.toml步骤:
- 读取当前domains.toml文件
- 找到合适的章节(核心基础设施、IoT设备或实用服务)
- 在高级配置章节之前追加新服务条目
- 使用编辑工具添加条目
模板:
toml
[[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
3.5 应用更改
Run the management script:
bash
cd /home/dawiddutoit/projects/network && ./scripts/manage-domains.sh applyExpected 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运行管理脚本:
bash
cd /home/dawiddutoit/projects/network && ./scripts/manage-domains.sh apply预期输出:
=== 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 successfully3.6 Manual Tunnel Step
3.6 手动隧道配置步骤
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 | |
提供清晰的Cloudflare Tunnel配置说明:
需要手动操作:添加Cloudflare Tunnel路由
1. 访问:https://one.dash.cloudflare.com
2. 导航至:Access -> Tunnels
3. 点击隧道:"pi-home"(或你的隧道名称)
4. 点击“Configure” -> “Public Hostname” -> “Add a public hostname”
5. 输入:
- Subdomain: {subdomain}
- Domain: temet.ai
- Type: {HTTP或HTTPS}
- URL: {backend_for_tunnel}
对于HTTPS服务:https://caddy:443
对于仅HTTP服务:http://caddy:80 或直接指向服务
6. 点击“Save hostname"隧道后端选择:
| 服务类型 | 隧道URL |
|---|---|
| 启用HTTPS | |
| 仅HTTP(IoT) | 直接指向服务: |
| Docker容器 | |
3.7 Verify Setup
3.7 验证设置
After tunnel configuration, run verification:
1. DNS Resolution (local):
bash
dig @192.168.68.135 {subdomain}.temet.ai +shortExpected: Returns the dns_ip configured
2. HTTPS Certificate:
bash
echo | openssl s_client -servername {subdomain}.temet.ai \
-connect {subdomain}.temet.ai:443 2>/dev/null | \
openssl x509 -noout -dates -issuerExpected: Valid certificate from Let's Encrypt
3. HTTP Response:
bash
curl -I https://{subdomain}.temet.aiExpected: HTTP/2 200 or 302 (redirect to login)
4. Service List:
bash
./scripts/manage-domains.sh listExpected: New service appears in list
隧道配置完成后,运行验证步骤:
1. DNS解析(本地):
bash
dig @192.168.68.135 {subdomain}.temet.ai +short预期结果:返回配置的dns_ip
2. HTTPS证书:
bash
echo | openssl s_client -servername {subdomain}.temet.ai \
-connect {subdomain}.temet.ai:443 2>/dev/null | \
openssl x509 -noout -dates -issuer预期结果:来自Let's Encrypt的有效证书
3. HTTP响应:
bash
curl -I https://{subdomain}.temet.ai预期结果:HTTP/2 200 或 302(重定向至登录页)
4. 服务列表:
bash
./scripts/manage-domains.sh list预期结果:新服务出现在列表中
Supporting Files
支持文件
| File | Purpose |
|---|---|
| Complete configuration options reference |
| Common service configuration examples |
| Pre-validation of subdomain and backend |
Validation Script Usage:
bash
python3 .claude/skills/add-subdomain/scripts/validate-subdomain.py grafana 192.168.68.135:3001| 文件 | 用途 |
|---|---|
| 完整配置选项参考 |
| 常见服务配置示例 |
| 子域名和后端地址预验证 |
验证脚本使用方法:
bash
python3 .claude/skills/add-subdomain/scripts/validate-subdomain.py grafana 192.168.68.135:3001Expected 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
成功:
- 服务条目已添加到domains.toml
- 已重新生成包含新服务块的Caddyfile
- 已创建Pi-hole DNS条目
- 已创建Cloudflare Access应用(如果require_auth=true)
- Caddy已重新加载并获取新证书
- 服务可通过https://{subdomain}.temet.ai访问
部分成功:
- 配置已应用但未配置隧道(已向用户发出提醒)
- 证书正在颁发中(可能需要1-2分钟)
失败迹象:
- domains.toml语法错误 -> 验证并修复 �- Caddy重载失败 -> 检查Caddyfile语法
- DNS无法解析 -> 检查Pi-hole日志
- 证书错误 -> 检查Cloudflare API令牌
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 domains
setup-new-domain-services - - For certificate issues
troubleshoot-ssl-certificates - - For authentication problems
diagnose-cloudflare-access
此Skill与以下组件集成:
| 组件 | 用途 |
|---|---|
| 中央配置源 |
| 应用配置更改 |
| 从domains.toml生成Caddyfile |
| 更新Pi-hole DNS条目 |
| 创建/更新Access应用 |
| Cloudflare Tunnel | 手动公共主机名配置 |
相关Skill:
- - 用于添加新顶级域名
setup-new-domain-services - - 用于证书问题排查
troubleshoot-ssl-certificates - - 用于认证问题排查
diagnose-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 |
| 指标 | 之前 | 之后 |
|---|---|---|
| 添加服务所需时间 | 15-30分钟(手动) | 2-5分钟(引导式) |
| 配置错误 | 常见(手动编辑) | 极少(已验证) |
| 所需文档 | 多个文件 | 单个Skill参考 |
| 一致性 | 参差不齐 | 标准化 |
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)
环境:
- 运行中的Docker,包含caddy、pihole容器
- 已连接的Cloudflare tunnel
- 包含API令牌的有效文件
.env
所需工具:
- 读写编辑权限(针对domains.toml)
- Bash(用于执行应用脚本和验证命令)
- Grep(用于重复检查)
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
- 不要添加重复子域名(先检查)
- 子域名不要使用大写字母
- 不要忘记手动隧道配置步骤
- 应用更改后不要跳过验证
- Linux系统上不要使用(使用实际IP)
host.docker.internal - 除非特别需要,否则不要同时启用HTTPS和HTTP
- 除非服务必须公开,否则不要设置require_auth=false
- 对于使用自签名证书的服务,不要跳过tls_insecure设置
Notes
备注
- The Pi IP is typically for services running on the Pi
192.168.68.135 - IoT devices need to work properly
strip_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
- 树莓派IP通常为(适用于运行在树莓派上的服务)
192.168.68.135 - IoT设备需要设置才能正常工作
strip_cf_headers = true - 使用自签名证书的服务需要设置
tls_insecure = true - 根路径重定向(如)使用
/admin/选项root_redirect - 隧道步骤为手动操作,因为Cloudflare Tunnel的API较为复杂
- 始终运行查看当前服务列表
./scripts/manage-domains.sh list