Ctrl K
ComunidadGuías…

docs/dockerhub.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<!--
Source of truth for the Docker Hub repository overview at
https://hub.docker.com/r/applegater/caddyui

Everything below this comment is published verbatim as the Hub "full
description". Edit here first, then publish; the publisher strips this
leading HTML comment. Keeping it in git is deliberate: the page silently
carried the pre-Apache-2.0 licence for a week after the relicense because
it only ever existed on Docker Hub.

The line below sets the Hub "short description" (the one-liner under the
repository name, 100 characters max). It is published alongside this file.

short-description: Open-source Caddy UI with guided publishing, certificate cleanup, TLS, SQLite, and MariaDB.
-->
# CaddyUI

A modern, self-hosted web UI for [Caddy](https://caddyserver.com/) — manage proxy hosts, redirections, SSL certificates, and advanced routes through a clean interface, without touching config files.

**Open source under the [Apache License 2.0](https://github.com/X4Applegate/caddyui/blob/main/LICENSE).** Free for personal, commercial, and internal use, with no hosted-service restrictions.

**Lighthouse:** Performance **99** · Accessibility **100** · Best Practices **100** · SEO **100**
*(measured on `/login` from Google's PageSpeed Insights — `:v2.12.53` and later)*

[GitHub](https://github.com/X4Applegate/caddyui) · [Issues](https://github.com/X4Applegate/caddyui/issues) · [CHANGELOG](https://github.com/X4Applegate/caddyui/blob/main/CHANGELOG.md) · [Releases](https://github.com/X4Applegate/caddyui/releases)

---

## 🚀 Quick start

```bash
docker pull applegater/caddyui:latest
```

SQLite is included and remains the zero-configuration default. For larger
installations, CaddyUI also supports MariaDB with concurrent connections,
platform-managed backups, and a built-in read-only SQLite → MariaDB migration
command. See the GitHub README's **MariaDB (optional enterprise backend)**
section and the included `docker-compose.mariadb.yml` overlay.

### Docker Compose

```yaml
services:
  caddy:
    # Batteries-included Caddy: DNS providers, CrowdSec, rate limiting, layer4.
    # Use `caddy:2-alpine` instead if you don't need those modules.
    image: applegater/caddyui-caddy:stable
    restart: unless-stopped
    ports: ["80:80", "443:443", "443:443/udp"]
    volumes:
      - caddy_data:/data
      - caddy_config:/config
    environment:
      CADDY_ADMIN: 0.0.0.0:2019
    command:
      - /bin/sh
      - -c
      - |
        mkdir -p /config/caddy
        [ -f /config/caddy/autosave.json ] || echo '{}' > /config/caddy/autosave.json
        exec caddy run --config /config/caddy/autosave.json --resume --adapter json

  caddyui:
    image: applegater/caddyui:latest
    restart: unless-stopped
    ports: ["8080:8080"]
    volumes:
      - caddyui_data:/data    # named volume — no chown needed
    environment:
      CADDY_ADMIN_URL: http://caddy:2019

volumes:
  caddy_data:
  caddy_config:
  caddyui_data:
```

> **💡 Fresh install:** On first boot Caddy has no saved config yet. The `command` above seeds an empty `{}` config automatically so Caddy starts cleanly without any extra steps. Without `--resume`, admin-API pushes from CaddyUI would be lost on every `docker compose restart`.

> **DNS-01 note:** Managed ACME certificates require a Caddy build containing the matching `caddy-dns` provider module, and the stock `caddy:2-alpine` image does not include those modules. The example above therefore uses the prebuilt **[`applegater/caddyui-caddy`](https://hub.docker.com/r/applegater/caddyui-caddy)** image — every DNS provider CaddyUI supports, the CrowdSec bouncer, rate limiting and layer4, on the current Caddy, for `amd64` and `arm64`. Prefer your own build? [`Dockerfile.caddy`](https://github.com/X4Applegate/caddyui/blob/main/Dockerfile.caddy) is its source, or supply any compatible Caddy build.

### Bind-mount note

If you bind-mount a host directory to `/data` instead of using a named volume, the host directory must be owned by uid `10001` (the non-root user the container runs as):

```bash
sudo chown 10001:10001 /path/to/caddyui_data
```

The container will print a clear error message at startup if the directory isn't writable.

---

## 🆕 What's new (v2.53 – v2.57)

- **v2.61.0 — Coraza WAF, and Layer4 on a shared port.** Middleware profiles can switch on the Coraza web application firewall (detect or block, OWASP Core Rule Set) — it needs the new `applegater/caddyui-caddy` image, which now includes the module. A Layer4 proxy can also share port 443/80 (SSH or RDP for one hostname next to normal HTTPS) through a caddy-l4 listener wrapper.
- **v2.60.0 — middleware profiles** (security headers, forward auth, IP restrictions, extra headers, configured once and picked on many hosts) and a **configurable fallback status** for unmatched requests. **v2.59.x — Forward Auth now works, unknown hosts answer 404, opt-in deletion propagation.**
- **v2.57.1 — security hardening release.** The live Caddy config, database backup, snapshots and Import from Caddy are admin-only; non-admin routes can no longer read Caddy's environment or files through `{env.…}` / `{file.…}` placeholders; API token scopes are enforced everywhere; the login lockout works. **Upgrade if you run user or viewer accounts.** Bundled Caddy is now 2.11.7. Set `CADDYUI_PUBLIC_URL` if you use password reset or invitations.
- **v2.57.0 — automatic deployment targets.** Pick the servers a Caddy Fleet entry always feeds, so every proxy host, redirection and advanced route saved on it is deployed to them without re-ticking **Also deploy to**.
- **v2.56.x — layer4 (TCP/UDP) routing** via `caddy-l4`, and **multi-arch images** (`linux/amd64` + `linux/arm64`) for both `applegater/caddyui` and `applegater/caddyui-caddy`.
- **v2.55.0 — share one managed certificate across fleet nodes:** one Caddy does the ACME order and CaddyUI pushes the certificate to the others.
- **v2.54.0 — configurable ACME DNS-01 resolver** for split-horizon DNS. **v2.53.0 — certificate file reads confined** to allowlisted directories.

Full release notes: <https://github.com/X4Applegate/caddyui/releases>

---

## ✨ Headline features

### 🔭 Fleet observability

CaddyUI v2.25 makes the source and state of fleet activity visible without replacing Caddy's normal logs:

- Live Traffic, Analytics, host drill-downs, and CSV exports use the node that actually handled each request
- Shared hostnames behind load-balanced Caddy instances remain distinguishable and filterable
- **Observe → Server Logs** streams a selected managed node at DEBUG, INFO, WARN, or ERROR
- Full runtime capture is memory-only and automatically stops after 15 minutes
- Managed ACME certificates show issuance, renewal, retry, success, revocation, and failure states per node
- Only the latest compact certificate state is persisted; raw runtime logs are never stored

The structured log listener should stay on a private Docker, LAN, WireGuard, or Tailscale network. CaddyUI adds named streams and does not redirect or suppress the node's existing container, journal, or file output.

### 📈 Detailed Prometheus metrics

CaddyUI v2.24 manages Caddy metrics without clobbering global options loaded elsewhere:

- Enable HTTP metrics and per-host labels on selected fleet servers
- Opt into `observe_catchall_hosts` with target-side Caddy 2.11+ validation
- Preserve unselected and externally-owned metrics configuration, including OTLP fields
- Copy each server's private Admin URL `/metrics` scrape target from Settings
- Apply metrics to fresh servers even before the first managed route exists

Keep the Caddy admin endpoint private. Prometheus should reach it through the same Docker, LAN, loopback, WireGuard, or Tailscale network used by CaddyUI.

### 🛡️ Fleet access logging and CrowdSec

CaddyUI v2.21 adds independent rotating file access logs and CrowdSec request protection:

- Target selected Caddy servers and HTTP, HTTPS, or both generated server types
- Keep Visitor Analytics active alongside native JSON or console file logs
- Configure rotation size, retained files, retention days, trusted proxies, and client IP headers
- Validate the `crowdsec` and `http.handlers.crowdsec` modules before enabling protection
- Store the CrowdSec API key without rendering it back into Settings
- Exclude exact hosts or Caddy path patterns and test LAPI connectivity after sync

The prebuilt `applegater/caddyui-caddy` image (built from the repository's `Dockerfile.caddy`) includes the required CrowdSec HTTP bouncer module. Custom Caddy images must include `github.com/hslatman/caddy-crowdsec-bouncer/http`.

### 🧹 Actionable certificate cleanup

CaddyUI v2.20.1 makes the Operations **Unused custom certificates**
recommendation precise and controllable:

- Names the affected PEM/file-path certificates directly
- Opens a filtered certificate list with an **Unused** marker on every affected row
- Excludes standalone managed ACME and wildcard definitions from the unused count
- Lets administrators dismiss the recommendation for the selected environment
- Automatically shows it again if the unused-certificate set changes

### 🧭 Guided enterprise operations

CaddyUI v2.20 organizes setup and daily work around operator intent and the active environment:

- Active Caddy server, connection state, last contact, last sync, and version in one operational header
- Live **Getting Started** readiness guide driven by the selected environment's real configuration state
- First-run journey covering administrator identity, Caddy connectivity, account security, optional DNS automation, and the first published service
- Guided Hostname → Upstream → Policy → Review workflow for publishing proxy hosts
- One-click access to the full advanced editor for experienced Caddy operators
- Stable semantic colors: blue action, green healthy, amber degraded, red failure, violet automation, gray neutral
- Caddy Fleet inventory plus an Identify → Connect → Authorize environment connection workflow
- Route inventory and host-health status with direct links into affected resources
- Live system load, memory, requests, and upstream health for administrators
- Prioritized reliability and security actions with one-click remediation paths
- Multi-server fleet availability, recent configuration activity, and live proxy reachability
- Persistent command search plus a global Create menu, Sync Caddy, and fleet management actions
- Workflow-based navigation for Traffic, Observe, Configuration, Developer, and Administration tasks
- Responsive light/dark layouts plus Carbon Orange, Forest, Rose, and Indigo themes

DNS automation is an optional readiness capability, so ordinary deployments can
reach 100% without provider credentials. The guide stays available after
initial setup and works as an ongoing environment checklist.

### 🏆 Perfect Lighthouse score

After an eleven-version perf + a11y wave (v2.12.38 → v2.12.48), CaddyUI's `/login` page hits **99/100/100/100** on Google PageSpeed Insights against a residential-ISP install:

- **FCP 0.5 s · LCP 0.9 s · TBT 0 ms · CLS 0.001** (desktop)
- Self-hosted Inter font + htmx + auth.css for unauth pages — zero external CDN dependencies on cold loads where it matters
- Service worker rewrite that auto-purges stale caches per release (no more "feels broken after upgrade")
- Externalized inline JS to `/static/app.js` so it caches across navigations
- Cloudflare Turnstile support out of the box (replaces Google reCAPTCHA — drops ~3 s of mobile JS exec)
- Skip-to-main-content link, `aria-current` nav, label↔input pairing across every form

### 🤖 AI assistant — bring your own backend

Opt-in floating chat button that answers Caddy / TLS / DNS questions and writes production-grade Caddyfile snippets. Pick any backend in **Settings → AI assistant**:

| Backend | Best for | What you need |
|---|---|---|
| **Ollama (local)** | Fully-offline, runs on your GPU | Reachable Ollama; recommended `qwen2.5:14b` / `gemma2:9b` |
| **Ollama Cloud** | MoE models that won't fit on a homelab GPU | API key from [ollama.com/settings/keys](https://ollama.com/settings/keys) |
| **Anthropic Claude** | Strongest Caddy reasoning out of the box | API key from [console.anthropic.com](https://console.anthropic.com); Haiku 4.5 / Sonnet 4.6 / Opus 4.7 |
| **OpenAI-compatible** | OpenAI itself + OpenRouter, Groq, Together, vLLM, LM Studio | Base URL + API key + model |

**AI auto-fill** — describe what you want in natural language (*"set up nextcloud at cloud.example.com pointing to nextcloud:80 with auto-SSL"*) and the assistant emits a `create_proxy_host` / `create_redirection` tool call. Click Apply on the confirmation card and the resource is created, the form is filled in for you, and Caddy is auto-synced. Every AI-driven exec writes an `ai_tool_call` activity-log entry. Works on Claude 4.x, GPT-4, qwen2.5+, llama3.1+, gemma2.

### 📤 Caddyfile export — round-trip with the existing import

Inverse of CaddyUI's existing `/caddyfile-import` paste flow. Click **Export Caddyfile** on `/proxy-hosts` to download every enabled proxy host, redirection, and raw route on the active server as a single Caddyfile snapshot:

```
example.com {
    @blocked path /.env* /wp-admin* /wp-login* /phpmyadmin* /.git/* /xmlrpc.php
    respond @blocked 403
    encode zstd gzip
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        ...
    }
    reverse_proxy backend:8080 {
        header_up X-Forwarded-Host {host}
        header_up X-Forwarded-Proto {scheme}
        header_up X-Real-IP {remote_host}
    }
}
```

Per-host `# Notes:` block lists settings that don't fit cleanly into Caddyfile syntax (maintenance windows, basic-auth users, etc.) so users see what was elided rather than silently losing it on round-trip. Stable sort by hostname so two exports of the same DB diff cleanly. Same RBAC scoping as the existing JSON exports — admin gets the full server config, non-admin only their own resources.

Per-host export also available from the proxy-host edit page.

---

## 🛡️ Other features at a glance

- **OIDC / SSO login** *(v2.52)* — sign in through an external identity provider (Authelia, Authentik, Keycloak, Google, …) alongside local password + TOTP, with verified-email matching and opt-in auto-provisioning
- **Scheduled off-host backups** *(v2.52)* — automatic SQLite snapshots to a directory on an interval, keeping the newest N, plus a **Back up now** button; point it at a mounted volume to keep copies off the host
- **Per-host rate limiting** *(v2.51)* — cap a host at *N requests per M seconds, per client IP* (429 on excess), via the `caddy-ratelimit` module built into `Dockerfile.caddy`
- **Per-host HTTP Basic Auth** *(v2.52.6)* — bcrypt-hashed accounts enforced by Caddy as the last gate before the upstream
- **Block an IP from analytics** *(v2.50)* — one-click **Block on this host** or **Block everywhere (fleet-wide)** straight from a visitor's drill-down page
- **Analytics drill-downs** *(v2.47 – v2.48)* — click a visitor, a path or a status class to see exactly what happened: top paths, status mix, user-agents, and errors by exact status code + path
- **Internal CA (`tls internal`)** *(v2.46)* — serve internal or local-network hosts from Caddy's built-in self-signed CA instead of ACME, no special Caddy build required
- **Configurable verification resolver** *(v2.49)* — point deploy/readiness DNS checks at internal or split-horizon resolvers instead of Cloudflare DoH
- **⌘K command palette** — global resource search across every proxy host, redirection, raw route, certificate
- **Bulk multi-select + drag-to-reorder** on every list page
- **DNS-01 cert auto-issuance** — selecting Managed DNS emits the matching ACME policy for ordinary and wildcard names
- **Standalone managed wildcards** — create auto-renewed DNS-01 wildcard certificates without a proxy host or pasted private key
- **Visible Auto TLS certificate selection** — the Caddy-managed table names the wildcard reused by each covered domain and labels per-host certificates clearly
- **Managed DNS** for Cloudflare, DigitalOcean, Hetzner, Porkbun, GoDaddy, Namecheap, Gandi, and Amazon Route 53 — auto-creates A records on save and reuses the credentials for DNS-01
- **Multi-server fleet management** — manage multiple Caddy instances from one UI, switch with a dropdown, and idempotently sync the selected environment's complete managed routing configuration to another server
- **Three-role RBAC** — admin / user / view, with per-user resource ownership and access groups whose members can manage each other's resources
- **2FA / TOTP**, login CAPTCHA (Turnstile or reCAPTCHA), session management
- **Snapshots** — one-click DB backup, auto-snapshot on sync
- **Notifications** — email (SMTP), webhook, [ntfy.sh](https://ntfy.sh) for cert-expiry + upstream-health alerts
- **Visitor analytics** — opt-in per-host traffic counters, top hosts, status-code mix, 24 h sparkline, with soft-start log forwarding so Caddy can boot while CaddyUI is offline
- **Carbon Orange theme** — alternative palette with cross-device sync via per-user DB column
- **PWA** — installable on desktop and mobile; offline-capable service worker

---

## 🔐 Managed wildcard certificates (v2.17+)

1. Save your provider credentials in **Settings → DNS**.
2. Open **Certificates → New**, choose **Managed ACME (DNS-01)**, select the saved credentials, and enter a subject such as `*.example.com`.
3. Select **Also configure on** to deploy the definition to additional Caddy servers. Each server obtains and renews its own certificate and keeps its own private key.
4. Leave covered proxy hosts on **Auto** TLS. CaddyUI automatically reuses the wildcard and suppresses unnecessary exact-host certificate orders.
5. Edit the managed certificate to inspect live deployment, issuer, expiry, and renewal health on every configured server.

No PEM upload, fake proxy upstream, or private-key transfer is required.

---

## 🏷️ Image tags

| Tag | What it points at |
|---|---|
| `:vX.Y.Z` | Specific release, immutable. Recommended for production. |
| `:stable` | The current release. Updated on every release. |
| `:latest` | Kept in lockstep with `:stable`. |

`:stable`, `:latest` and the newest `:vX.Y.Z` all resolve to the same image.

> **`:preview` is gone.** It was once a rolling per-commit channel. The tag was deleted from Docker Hub in October 2026 — if you still reference it, switch to `:stable` or pin a version.

Multi-arch: `linux/amd64` + `linux/arm64`. Scratch base image, runs as non-root uid `10001`.

---

## 🔧 Configuration

| Environment variable | Default | Purpose |
|---|---|---|
| `CADDY_ADMIN_URL` | `http://caddy:2019` | Caddy's admin API (the docker service name in the same compose network) |
| `CADDYUI_DB_DRIVER` | `sqlite` | Database backend: `sqlite` or `mariadb` |
| `CADDYUI_DB` | `/data/caddyui.db` | SQLite database path |
| `CADDYUI_DB_DSN` | (none) | MariaDB DSN; required when `CADDYUI_DB_DRIVER=mariadb` |
| `CADDYUI_LISTEN` | `:8080` | HTTP listen address |
| `CADDYUI_INGEST_LISTEN` | `:9019` | Structured Caddy log ingest for analytics, certificate lifecycle, and temporary runtime streams (empty string disables all three) |
| `CADDYFILE_PATH` | `/etc/caddy/Caddyfile` | Optional — path to a Caddyfile mounted into the CaddyUI container. Its `(name) { ... }` snippet definitions are auto-loaded so `import <name>` works in Advanced routes, Caddyfile paste import, and a proxy host's Advanced config; site blocks and global options in it are never used |
| `CADDYUI_PUBLIC_URL` | (none) | Externally visible origin, e.g. `https://caddyui.example.com`. Used for the links in password-reset and invitation emails; without it the link is built from the request's `Host` header |
| `CADDY_ADMIN_USER` / `CADDY_ADMIN_PASS` | (none) | Optional HTTP basic auth for Caddy's admin endpoint when proxied |

---

## 📜 License

[Apache License 2.0](https://github.com/X4Applegate/caddyui/blob/main/LICENSE) — CaddyUI is open source.

- **Free** for everyone — personal, commercial, and internal use alike.
- **Modify and redistribute** freely, including as part of your own products or hosted/managed services.
- **Patent grant** included, and contributions are welcome under the same license.

The only conditions are the usual Apache-2.0 ones: keep the license and copyright notices, and state significant changes you make.

> CaddyUI was previously distributed under the CaddyUI Source Available License 1.0. It was relicensed to **Apache-2.0 in September 2026** — the old commercial-use and hosted-service restrictions no longer apply.

---

## 🐛 Found a bug?

Open an issue on GitHub: https://github.com/X4Applegate/caddyui/issues

— Richard