caddyserver/caddy
How to contribute
This section is for developers working on Caddy itself — adding modules, fixing bugs in the core, or tightening the Caddyfile adapter. The user-facing docs at caddyserver.com/docs are the right place for "how do I configure feature X".
The authoritative contributor guide lives at .github/CONTRIBUTING.md and AGENTS.md. This page summarizes the parts you most need on day one.
Pages in this section
- Development workflow — branches, commits, PR shape, signing the CLA
- Testing —
go test, table-driven tests, thecaddytest.Testerintegration helper - Debugging — log levels,
caddy adapt, common reload failures, pprof - Patterns and conventions — module registration, lifecycle interfaces, error flow, naming
- Tooling —
golangci-lint,goreleaser,xcaddy, the GitHub Actions matrix
Definition of done
Before opening a PR (taken from AGENTS.md):
| Gate | Command | Notes |
|---|---|---|
| Tests pass | go test -race -short ./... |
CI runs on Linux, macOS, Windows |
| Lint clean | golangci-lint run --timeout 10m |
rules in .golangci.yml |
| Builds | go build ./... |
must compile on every supported OS |
| Benchmarks (if perf-sensitive) | go test -bench=. -benchmem |
required for optimization claims |
caddyhttp and caddytls are flagged in AGENTS.md as security-critical. Changes there get extra review scrutiny.
What a good PR looks like
- One topic per PR. Refactoring a function and adding a feature in the same diff makes review hard.
- A test for every behavior change. New modules should ship a test file in the same directory.
- Caddyfile-visible behavior gets a fixture in
caddytest/integration/caddyfile_adapt/(input + expected JSON). - Backwards-incompatible changes need explicit justification — the project's mission statement is stability.
AI-assisted contributions
Per AGENTS.md, AI-generated or AI-assisted code must be:
- Disclosed — say so in the PR, including which agent/model.
- Fully comprehended — you can explain every line yourself.
- Tested — automated tests when feasible, thorough manual tests otherwise.
- Licensed — you have verified output is not plagiarized or copied from incompatibly licensed code.
- Covered by a CLA — the human user has signed the Contributor License Agreement.
The project's stance is that you, the human, are responsible for what you submit.
Where things live
| If you want to… | Look here |
|---|---|
| Add an HTTP handler module | modules/caddyhttp/<name>/ (register http.handlers.<name>) |
| Add an HTTP matcher | modules/caddyhttp/matchers.go or a new file in modules/caddyhttp/ |
| Add a Caddyfile directive | caddyconfig/httpcaddyfile/directives.go (ordering) plus UnmarshalCaddyfile on the module |
| Add a TLS issuer | modules/caddytls/<name>issuer.go (register tls.issuance.<name>) |
| Add a config adapter | caddyconfig/<name>adapter/ and call RegisterAdapter |
| Add an admin endpoint | implement caddy.AdminRouter on your module |
| Add an integration test | caddytest/integration/... with caddytest.NewTester(t) |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.