Go plugins are part of the language since 1.8 and allow dynamically loading go packages¹ similar to modules in Apache or nginx’s
load_module. Functions and variables from these packages can then be used as usual.
Caddy has a large ecosystem of plugins for e.g. ACME challenges. However in many circumstances it is impossible or undesirable to use a custom compiled version of caddy. This might be the case when the use does not have control over the binary but only configuration+content or the binary is immutable by other means for example when using caddy distributed as a container² or snap³. And even if the user has the possibility to change the binary this might still be undesired which is why Fedora and its derivatives (RHEL) as well as Debian and its derivatives (Ubuntu) disable the respective subcommands4,5 (have not checked other distros). Using these officially distributed packages also has advantages regarding support and interoperability amongst other things. Security enforcements from SELinux or Apparmor also play into this.
Go plugins enable users to get these plugins separately and then tell caddy to load them on startup. This way ACME challenge providers and other plugins can be used even if they are not part of the original binary.
An alternative would be to bundle all plugins by default. Telegraf an agent for monitoring data does this for example to include hundreds of input, output and transformation plugins for data. The resulting binary is still very small. However this would either only include official caddy plugins or require some central information about trusted third-party plugins to include. Even then this still does not allow for self-made plugins (e.g. a custom libdns provider) to be used. Ultimately telegraf still bundles all plugins but also supports dynamically loading plugins from a directory (PR)
A mismatch in signature of the exposed symbols can lead to panics. However this is no different from other panics caused by plugins today. Additional care also has to be taken to ensure that both the server executable and the plugin were compiled with the same compiler version. However in most cases this is not a problem. E.g. when compiling a plugin for Fedora’s Caddy package it is compiled with the same compiler version as is shipped with the distribution itself.
Plugins are also not supported on windows currently though this is not a problem as long as the current method of including plugins at compile time is not removed.
# First few links inside a code block due to "new user" limit ¹ https://pkg.go.dev/plugin ² https://hub.docker.com/_/caddy ³ https://snapcraft.io/caddy ⁴ https://src.fedoraproject.org/rpms/caddy/blob/28051782774a8e9f93d0cdf2b54e412e9dd32acc/f/0001-Disable-commands-that-can-alter-the-binary.patch ⁵ https://salsa.debian.org/go-team/packages/caddy/-/blob/015b8feab1d5dc91d84e8dd81756b4676c24c794/debian/patches/0004-Remove-dysfunct-commands.patch