Product-code half (fleet gate, capabilities endpoint, offline feature migration, PREMIUM_FEATURES completion) lives in the dashcaddy repo, branch dc/DC-165-uniformity — judged as one bundle. Site edits (all claims verified against product source, see EVIDENCE [9]): - template count 77 -> 78 EVERYWHERE (page.tsx, features, pricing, docs, blog bodies + manifest.ts frontmatter per three-way consistency rule, AppShowcase, DocsLayout, FaqSection). Source of truth: APP_TEMPLATES keys == 78. - internal-identifier leak sweep: 85 occurrences of *.sami (internal TLD), an internal Git host URL, a private venv path, and a server-local repo path in pricing comment -> replaced with the documented .home style / generic wording. status.sami replaced by dashcaddy.local (product default dashboardHost). Verified ZERO remaining in rebuilt out/. - advertise as Premium (owner decision 2026-10-09): pricing premium list + FAQ + docs/premium table + two new deep-dive sections (Workflow Automation: the five bundled ids from bundled-workflows.js; Scheduled Backups: schedule fields from the /backups/schedule schema, manual one-click + DR explicitly noted as free). - calendar widget + hosted-Radicale auto-wiring advertised (features page chip + new docs/catalog/radicale install guide following house template structure; syncthing page mirrored for the placeholder conventions). - Connect AI one-click key flow advertised (features chip). - MCP card softened: 'entire infrastructure' -> the real tool scope + pointer to GET /api/v1/capabilities (public ground-truth manifest). - llms.txt: capabilities endpoint pointer + 'prefer it over static prose' + MCP tool examples + premium gate list; robots.txt gains LLMs-Txt line. - NOTE: a parked unrelated work-in-progress (dc-seo-r8 blog edits) was stashed before the build and is NOT in this commit. Build gate: rm -rf .next out && npm run build -> clean, 123 static pages, out/ greps zero stale counts/leaks.
300 lines
16 KiB
TypeScript
300 lines
16 KiB
TypeScript
import Navbar from '@/components/Navbar';
|
|
import Footer from '@/components/Footer';
|
|
import DocsLayout from '@/components/docs/DocsLayout';
|
|
|
|
export default function DocsIntegrationsPage() {
|
|
return (
|
|
<div className="flex min-h-screen flex-col bg-surface-950 text-surface-50">
|
|
<Navbar />
|
|
<DocsLayout
|
|
title="Infrastructure Integrations"
|
|
intro="DashCaddy is most valuable when its supporting integrations are healthy. This guide explains each layer it expects to work with, what it does, and how the pieces fit together into a single control plane."
|
|
>
|
|
<p>
|
|
DashCaddy is not a monolith. It is an orchestration layer that drives several independent infrastructure
|
|
components — a container runtime, a reverse proxy, a DNS server, a certificate authority, a private network,
|
|
a metrics pipeline, and an AI surface. Each integration is swappable, observable, and independently debuggable.
|
|
When you understand what each layer is responsible for, you can pinpoint failures in minutes instead of guessing.
|
|
</p>
|
|
<p>
|
|
This guide walks every integration in depth: what it does, how DashCaddy talks to it, the configuration it
|
|
expects, and a code example where relevant. Read it end-to-end once, then come back to specific sections when
|
|
something goes wrong. For a quick diagnostic flow, see the <a href="/docs/troubleshooting">Troubleshooting</a> guide.
|
|
</p>
|
|
|
|
<h2>Docker — container runtime</h2>
|
|
<p>
|
|
Docker (and Docker Compose) is the runtime foundation for every deployment workflow, container lifecycle action,
|
|
service discovery sweep, and template-based launch. DashCaddy communicates with the Docker daemon over the
|
|
Unix socket (<code>/var/run/docker.sock</code>) to start, stop, restart, inspect, and adopt containers, and to
|
|
deploy the <strong>78 one-click application templates</strong> from the catalog.
|
|
</p>
|
|
<p>
|
|
The daemon connection is established at startup. If the socket is missing or permissioned for a different user,
|
|
DashCaddy's <code>/readyz</code> probe will fail immediately — a fast signal that the runtime layer is broken.
|
|
During the <strong>Smart Defaults Wizard</strong>, DashCaddy probes the socket, reports the Docker version, and
|
|
suggests socket paths if the default is not found.
|
|
</p>
|
|
<p>
|
|
Optional <strong>Docker Swarm</strong> support (Premium) extends the same model across multiple nodes. When
|
|
Swarm mode is enabled, DashCaddy switches from single-container operations to service-level operations, managing
|
|
placement, replicas, and rolling updates across the cluster. See <a href="/docs/premium">Premium Features</a>.
|
|
</p>
|
|
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# Verify the Docker socket DashCaddy will use
|
|
docker version
|
|
ls -l /var/run/docker.sock
|
|
|
|
# The DashCaddy container needs the socket mounted:
|
|
docker run -d \\
|
|
-v /var/run/docker.sock:/var/run/docker.sock \\
|
|
-p 3000:3000 \\
|
|
ghcr.io/dashcaddy/dashcaddy:latest`}</code></pre>
|
|
<blockquote className="border-l-4 border-brand-500/50 bg-brand-500/5 p-4 rounded-r-lg">
|
|
<p className="text-surface-300">
|
|
<strong className="text-brand-400">Note:</strong> Mounting the Docker socket grants full container control.
|
|
In production, run DashCaddy behind Tailscale or a firewall so the dashboard is not exposed to the public
|
|
internet.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<h2>Caddy — reverse proxy & automatic HTTPS</h2>
|
|
<p>
|
|
Caddy is the reverse proxy and automatic HTTPS layer. Every service you publish through DashCaddy gets a Caddy
|
|
route that terminates TLS and proxies traffic to the upstream container. DashCaddy communicates with the
|
|
<strong> Caddy Admin API</strong> (default <code>localhost:2019</code>) to create, update, and remove routes,
|
|
and to trigger certificate issuance on demand.
|
|
</p>
|
|
<p>
|
|
Caddy's built-in internal CA auto-generates and renews certificates for every published service. For
|
|
public domains, Caddy can also use ACME (Let's Encrypt / ZeroSSL) automatically. The choice between
|
|
internal and public CA is made per-service at publish time, so you can mix internet-facing and lab services
|
|
on the same host without conflict.
|
|
</p>
|
|
|
|
<h3>Caddyfile-as-Code</h3>
|
|
<p>
|
|
Instead of hand-editing Caddyfiles, DashCaddy exposes a <strong>visual Caddyfile-as-Code builder</strong>. You
|
|
describe the desired route — hostname, upstream, TLS options, headers, redirects, compression — and DashCaddy
|
|
generates the valid Caddy configuration and applies it atomically through the Admin API. Configuration is
|
|
versioned and reviewable, so every change is auditable and reversible.
|
|
</p>
|
|
<p>
|
|
The generated config is rendered in the service's <strong>Caddyfile-as-Code view</strong>, so you can
|
|
inspect exactly what Caddy will receive before it is applied. If a route misbehaves, compare the rendered config
|
|
against your expectation. Invalid configs are rejected before they reach Caddy, preventing the proxy from
|
|
reloading into a broken state.
|
|
</p>
|
|
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# Example generated Caddyfile (internal CA, lab hostname)
|
|
media.lab {
|
|
tls internal
|
|
|
|
encode zstd gzip
|
|
|
|
reverse_proxy localhost:8096 {
|
|
header_up X-Forwarded-Host {host}
|
|
header_up X-Real-IP {remote_host}
|
|
}
|
|
|
|
header {
|
|
Strict-Transport-Security "max-age=31536000"
|
|
X-Content-Type-Options nosniff
|
|
}
|
|
}`}</code></pre>
|
|
|
|
<h2>Technitium DNS — DNS automation</h2>
|
|
<p>
|
|
Technitium DNS is the DNS automation target for record creation and removal. When you deploy or adopt a service,
|
|
DashCaddy creates the corresponding A or CNAME record through the Technitium REST API so the new hostname
|
|
resolves immediately. Removing a service cleans up the record automatically — no orphaned DNS entries.
|
|
</p>
|
|
<p>
|
|
DashCaddy needs three pieces of information to drive Technitium: the server URL, an API token with write access
|
|
to the target zone, and the zone name itself. All three are configured during the Smart Defaults Wizard or
|
|
later under <strong>Settings → DNS</strong>. A common failure mode is a token with the wrong scope — it can
|
|
read records but not create them — which fails silently. Always verify the token can write to the zone you
|
|
intend to use.
|
|
</p>
|
|
<p>
|
|
Internal zones (e.g. <code>.lab</code>) only resolve if the client uses Technitium as its resolver. Public
|
|
resolvers like 8.8.8.8 will not know about them. For remote clients, either point their DNS at Technitium
|
|
directly or use <strong>Tailscale</strong> with a MagicDNS / split-DNS setup.
|
|
</p>
|
|
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# Create a record directly via the Technitium API (debugging)
|
|
curl -X POST "http://technitium-host:5380/api/zones/records/add" \\
|
|
-d "token=***" \\
|
|
-d "zone=lab" \\
|
|
-d "domain=media.lab" \\
|
|
-d "type=A" \\
|
|
-d "ipAddress=192.168.1.50"
|
|
|
|
# Verify the record resolves through Technitium
|
|
dig @technitium-host media.lab +short`}</code></pre>
|
|
|
|
<h2>DashCA — internal certificate authority</h2>
|
|
<p>
|
|
DashCA is the certificate distribution system that makes internal HTTPS practical. Caddy's internal CA
|
|
issues certificates automatically for <code>.lab</code> and other private hostnames; DashCA provides the
|
|
distribution page where you download the root certificate and install it as a trusted CA across your devices.
|
|
Once trusted, every internal service is served over valid HTTPS with no browser warnings.
|
|
</p>
|
|
<p>
|
|
The root certificate must be installed on <strong>each client device</strong> that will access internal
|
|
services — not just the server. A macOS laptop, a Windows desktop, and an Android phone each need the cert
|
|
installed separately. The DashCA page includes per-platform instructions (macOS Keychain, Windows certmgr,
|
|
Linux <code>update-ca-certificates</code>, and mobile profiles) to make this straightforward.
|
|
</p>
|
|
<p>
|
|
After installing the root CA, restart your browser or clear its certificate cache. Chrome and Firefox maintain
|
|
separate trust stores on some platforms; Firefox may need the import done from within its own settings.
|
|
</p>
|
|
|
|
<h2>Tailscale — private access</h2>
|
|
<p>
|
|
DashCaddy fits naturally into private access patterns with <strong>Tailscale</strong>. Services can be published
|
|
only on a Tailnet, keeping them off the public internet while still benefiting from DashCaddy's DNS, proxy,
|
|
and TLS automation. This is ideal for home labs, internal team tools, and any service that should never be
|
|
internet-facing.
|
|
</p>
|
|
<p>
|
|
The typical setup runs Tailscale on the DashCaddy host, advertises the host on the Tailnet, and optionally
|
|
enables MagicDNS so Tailnet hostnames resolve without a separate DNS server. Combine with Technitium split-DNS
|
|
for the most seamless experience: Technitium handles <code>.lab</code> zones for Tailnet clients, while public
|
|
domains resolve normally.
|
|
</p>
|
|
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# Install and authenticate Tailscale on the DashCaddy host
|
|
curl -fsSL https://tailscale.com/install.sh | sh
|
|
tailscale up --advertise-routes=192.168.1.0/24 --accept-routes
|
|
|
|
# Verify the host is on the Tailnet
|
|
tailscale status
|
|
tailscale ip
|
|
|
|
# From another Tailnet device, reach the service directly
|
|
curl -k https://dashcaddy-host.tailnet-name.ts.net/media.lab`}</code></pre>
|
|
<blockquote className="border-l-4 border-brand-500/50 bg-brand-500/5 p-4 rounded-r-lg">
|
|
<p className="text-surface-300">
|
|
<strong className="text-brand-400">Tip:</strong> If you publish services only on the Tailnet, set Caddy to
|
|
bind to the Tailscale interface IP rather than <code>0.0.0.0</code>. This guarantees the service is
|
|
unreachable from the LAN even if the firewall is misconfigured.
|
|
</p>
|
|
</blockquote>
|
|
|
|
<h2>Prometheus & Grafana — metrics & observability</h2>
|
|
<p>
|
|
DashCaddy exports metrics in Prometheus format at <code>/metrics</code>, including service health, container
|
|
status, request counts, certificate expiry, and system resource indicators. Point your Prometheus scraper at
|
|
the endpoint and build Grafana dashboards on top for long-term observability, capacity planning, and alerting.
|
|
</p>
|
|
<p>
|
|
The metrics endpoint is unauthenticated by default for internal scraping. If your Prometheus instance is on a
|
|
different host or network, place it behind the same Tailscale Tailnet or restrict access with a reverse-proxy
|
|
basic-auth rule in Caddy.
|
|
</p>
|
|
<pre className="mt-4 overflow-x-auto rounded-lg border border-surface-700/50 bg-surface-950/80 p-4 text-sm"><code>{`# prometheus.yml — scrape DashCaddy
|
|
scrape_configs:
|
|
- job_name: 'dashcaddy'
|
|
metrics_path: /metrics
|
|
static_configs:
|
|
- targets: ['dashcaddy-host:3000']
|
|
# Optional: increase scrape frequency for faster alerting
|
|
scrape_interval: 15s
|
|
scrape_timeout: 10s`}</code></pre>
|
|
<p>
|
|
Useful PromQL starters once data is flowing: <code>dashcaddy_service_health == 0</code> (unhealthy services),
|
|
<code> rate(dashcaddy_http_requests_total[5m])</code> (request throughput), and
|
|
<code>dashcaddy_cert_expiry_days < 14</code> (certificates expiring soon).
|
|
</p>
|
|
|
|
<h2>MCP Server & AI assistants</h2>
|
|
<p>
|
|
The built-in <strong>MCP (Model Context Protocol) Server</strong> exposes DashCaddy operations to AI assistants
|
|
and external automation. Combined with the <strong>AI Intent Router</strong>, you can issue natural-language
|
|
commands — “restart the media server”, “deploy the postgres template”, “is the
|
|
database healthy?” — and have DashCaddy execute the real infrastructure action through the standard MCP
|
|
tool interface.
|
|
</p>
|
|
<p>
|
|
This turns DashCaddy into an AI-operable control plane: the same operations available in the dashboard are
|
|
available as MCP tools, so an assistant like Claude or GPT can inspect and manage your infrastructure directly.
|
|
Full setup instructions, the tool catalog, and intent examples are in the <a href="/docs/api">API and Automation</a> guide.
|
|
</p>
|
|
|
|
<h2>How the layers fit together</h2>
|
|
<p>
|
|
The table below maps each integration to the layer it provides and the DashCaddy feature that consumes it.
|
|
When a service fails, locate the row whose symptom matches, then debug that integration directly.
|
|
</p>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th>Layer</th>
|
|
<th>Integration</th>
|
|
<th>DashCaddy feature that uses it</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>Runtime</strong></td>
|
|
<td>Docker / Docker Compose</td>
|
|
<td>Deploy, adopt, lifecycle, templates, service discovery</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Proxy</strong></td>
|
|
<td>Caddy (Admin API)</td>
|
|
<td>Reverse proxy routes, Caddyfile-as-Code, auto HTTPS</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>DNS</strong></td>
|
|
<td>Technitium DNS</td>
|
|
<td>Automatic A/CNAME record creation & cleanup</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Trust</strong></td>
|
|
<td>DashCA (internal CA)</td>
|
|
<td>Root certificate distribution for internal HTTPS</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Access</strong></td>
|
|
<td>Tailscale</td>
|
|
<td>Private networking, Tailnet-only publishing</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Observe</strong></td>
|
|
<td>Prometheus / Grafana</td>
|
|
<td>Metrics export, alerting, long-term dashboards</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Automate</strong></td>
|
|
<td>MCP Server + AI Intent Router</td>
|
|
<td>Natural-language ops, AI assistant tool surface</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Secure</strong></td>
|
|
<td>Security Center + audit log</td>
|
|
<td>Event aggregation, change auditing, RBAC</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<h2>Operational flow: deploy to observe</h2>
|
|
<p>
|
|
When everything is wired correctly, a single service publish triggers the full chain automatically:
|
|
</p>
|
|
<ol>
|
|
<li><strong>Deploy / Adopt</strong> — Docker runs the container (or adopts an existing one).</li>
|
|
<li><strong>Publish</strong> — Caddy creates the reverse-proxy route and requests a TLS certificate.</li>
|
|
<li><strong>Resolve</strong> — Technitium DNS creates the hostname record so the domain resolves.</li>
|
|
<li><strong>Trust</strong> — DashCA distributes the root CA so clients accept the internal cert.</li>
|
|
<li><strong>Observe</strong> — health checks, Prometheus metrics, and WebSocket live updates report state.</li>
|
|
<li><strong>Secure</strong> — Security Center aggregates events; audit logging records every change.</li>
|
|
</ol>
|
|
<p>
|
|
Each step is independently observable. If a service is unreachable, walk the chain in order — the first broken
|
|
step is your failure. For the full diagnostic procedure, see <a href="/docs/troubleshooting">Troubleshooting</a>.
|
|
</p>
|
|
</DocsLayout>
|
|
<Footer />
|
|
</div>
|
|
);
|
|
}
|