Chapter 1

Theory

The function of a module is to receive configuration to then turn it into action, i.e. take declarative input into business logic. At its core, Caddy is a configuration loading management system which comes with a logger, storage backend, configuration adapters, and an administration endpoint. This is evident in the structure of its configuration:

{
	"admin": {},
	"logging": {},
	"storage": {•••},
	"apps": {•••}
}

Every one of the aforementioned compoenents has modular parts within it. The native configuration language is JSON. The values within the apps object can be anything that is a Caddy app, which themselves are Caddy modules.

Caddy modules are implementations of interfaces. The most barebones Caddy module implements the interface caddy.Module, defined as:

type Module interface {
	// This method indicates that the type is a Caddy
	// module. The returned ModuleInfo must have both
	// a name and a constructor function. This method
	// must not have any side-effects.
	CaddyModule() ModuleInfo
}

The type caddy.ModuleInfo is defined as:

type ModuleInfo struct {
	// ID is the "full name" of the module. It
	// must be unique and properly namespaced.
	ID ModuleID

	// New returns a pointer to a new, empty
	// instance of the module's type. This
	// method must not have any side-effects,
	// and no other initialization should
	// occur within it. Any initialization
	// of the returned value should be done
	// in a Provision() method (see the
	// Provisioner interface).
	New func() Module
}
type ModuleID string