RFC: Caddy as an opt-in web server provider — two architectures, a request for direction #4615
masonjames
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Caddy support has been requested since January 2025 (#1246, steady +1s since). Two implementations now exist, built on fundamentally different architectures. Before more code gets written, this RFC asks the maintainers for a direction call.
The two architectures
A. Label-driven (caddy-docker-proxy) — @Siumauricio's
feat/caddybranch (April 2025, ~354 lines). Caddy runs with the caddy-docker-proxy module; routes come from container labels, mirroring how Dokploy already drives Traefik's docker provider.B. Central config generation — PR #4534. Dokploy's database stays the source of truth; the server generates a complete Caddy JSON config (one fragment per domain), validates it, and reloads via Caddy's admin API. Includes guarded Traefik→Caddy migration tooling with dry-run/apply/rollback.
Honest comparison
caddyimage onlycustomCertResolver)A is genuinely simpler and matches Dokploy's existing label mental model. B's bet is that for a provider switch (not greenfield), correctness lives in the migration path — and that a generated, validated artifact is easier to support than emergent label state. Both are defensible; that's exactly why this needs a maintainer call.
"Why Caddy at all?" — answering @russorat directly
Fair question, asked on #1246. Concrete answers from running PR #4534's provider in production since 2026-06-01 (2-node swarm, ~30 services, ~40 domains, Cloudflare in front):
Honest caveats: the Coolify note russorat linked is about support burden, not a technical defect — and that concern is valid here too. So: Traefik stays the default, untouched. Caddy is opt-in behind a guarded migration. Our own first cutover attempt (2026-05-23) failed and rolled back — unresolved swarm DNS names, a portless upstream, an IP-allowlist route going public — which is precisely why the migration tooling is now fail-closed (live upstream preflight, blocking warnings, rollback snapshots). Second cutover succeeded; no provider-caused edge incidents since.
Current state of PR #4534
120 files / +27,881 looks unreviewable, but: ~8.5k is a generated Drizzle snapshot, ~7.8k is tests (29 new test files), ~500 is docs. Real source is ~11k — still large, hence the split below. (The
size:XSauto-label is wrong; the labeler appears to have mis-sized it.) CI has never run — first-time-contributor workflow approval was never granted.Proposed stacked split
Rather than asking anyone to review #4534 as-is:
webServerRouter, and fixes two existing upstream bugs found during this work: compose domains bypassing route refresh, and preview-deployments hardcoding the provider path. Valuable even if Caddy is rejected.customCertResolver).PRs 3–5 only proceed if the answer to the architecture question is B (or "B, modified").
The ask
I'll keep running this in production either way and can share configs, metrics, or failure reports on request.
Beta Was this translation helpful? Give feedback.
All reactions