Although the native configuration language of Caddy is JSON, Caddy is known for its Caddyfile configuration format, which is more human-friendly. An example of a production-ready Caddyfile is the one I use for my own blog (sans the logging configuration):
www.example.com, example.com, localhost {
root * /var/www/public
file_server
encode gzip
}
Another Caddyfile is:
www.example.com, example.com, localhost {
@health {
path /health
}
respond @health {
body "ok"
}
@notbrowser {
not {
header_regexp (?i)mozilla/(?P<version>\d+\.\d+)
}
}
respond @notbrowser {
body "Go away, bot!"
status 403
}
file_server /blog*
}
Thus supporting Caddyfile for your module is a great UX addition and likely increases adoption. Inspired by the idiomatic Go-way of supporting format marshalling, the best practice for supporting Caddyfile is done by implementing the caddyfile.Unmarshaler 1 interface and calling the respective function:
httpcaddyfile.RegisterDirective(dir string, setupFunc UnmarshalFunc) 2httpcaddyfile.RegisterGlobalOption(opt string, setupFunc UnmarshalGlobalFunc) 2httpcaddyfile.RegisterHandlerDirective(dir string, setupFunc UnmarshalHandlerFunc) 2type Unmarshaler interface {
UnmarshalCaddyfile(d *Dispenser) error
}
Merely implementing the interface allows other modules that host your module and know your full module ID to be able to load your module. If your module is an HTTP handler, it’s best to call httpcaddyfile.RegisterHandlerDirective 2 to have support of matchers automagically added to your directive rather than merely calling httpcaddyfile.RegisterDirective 2.
Add Caddyfile support to your module, including support for matchers
Remember: Use xcaddy list-modules and xcaddy run --config <config_file> --adapter caddyfile to test your implementation
Use this Caddyfile to test the implementation:
localhost {
route {
dump_headers /debug*
respond "Hello, world!"
}
}