Using Docker
happyDomain is sponsored by Docker. You’ll find the official container image on the Docker Hub.
The image runs happyDomain as a single process with a LevelDB database stored on disk: no extra database to configure. Every checker shipped with happyDomain is built into the binary, so a single container is already a complete, fully featured happyDomain.
Supported tags and architectures
All tags are built for amd64, arm64 and arm/v7 and are based on Alpine.
Currently available tags:
latest: the most up-to-date version, corresponding to the master branch.
Tags suffixed with -cgo contain a dynamically linked build, the only one
able to load plugins. Use them only if
you need that: the default tags are statically built, smaller and more
portable, but they ignore any plugin directory.
Quick start (single container)
For a quick test or personal use, pass HAPPYDOMAIN_NO_AUTH=1 to skip account management:
Data are stored inside the container. To keep them across restarts, attach a volume:
For a production single-container setup that sends e-mail:
Recommended deployment: docker compose
This is the setup we recommend for almost every deployment, from a personal instance to a company-wide one. It is the same file you’ll find at the root of the happyDomain repository.
Beside happyDomain itself, it runs the few third-party backends that some checkers need to reach (DNSViz, Zonemaster and the Matrix federation tester), plus a local recursive resolver so that DNS lookups don’t depend on your hosting provider’s resolver.
Save the file as docker-compose.yml and run docker compose up -d.
With this stack, all the checkers shipped with happyDomain are available: they run inside the happyDomain process, and the three services above only provide the external analysis engines two or three of them rely on.
Where do checkers run?
There are two separate questions here, and mixing them up is a common source of confusion.
First, how does happyDomain know a checker exists? Only two answers:
- built-in: the checker is compiled into the happyDomain binary. Every checker we ship is available this way, and it’s what you get with the deployments above;
- plugin: a shared library (
.so) dropped into a directory passed with-plugins-directory, loaded at start-up. This is the only way to add a checker that is not part of happyDomain (one you wrote for your own needs, or one from a third party), without patching and rebuilding the server. It requires a-cgoimage tag: the default image is a static build with no plugin support (see Plugins).
Then, where does the work actually run? A registered checker runs inside the
happyDomain process by default. If you set
HAPPYDOMAIN_CHECKER_<ID>_ENDPOINT, it instead delegates the collection to a
standalone container exposing that checker over HTTP.
The important consequence: a checker container is not a way to add a checker.
The endpoint setting only exists for checkers happyDomain already knows about,
so a home-made checker must first be loaded as a plugin, and only then may you
point it at a container.
For a given checker, running it locally or delegating it to a container performs exactly the same checks and produces the same results. Delegating buys you process isolation and the ability to scale a single checker independently; it costs you a lot more RAM, more moving parts and a much less pleasant debugging experience when one of them misbehaves.
Unless you’re operating at a scale where that trade-off pays off, or you need a checker that isn’t shipped with happyDomain, stay with the compose file above. If you do need it, see Running checkers as separate containers.
Updating the stack
1. Check whether the reference docker-compose.yml has changed. Upgrading
the images is not always enough: a new version may come with a new service (a
checker that needs its own backend, for instance) or new settings to declare.
Compare your file with the one in
the happyDomain repository,
and port the changes that concern you into your own copy:
2. Pull the images and recreate the containers.
--pull always fetches the latest image for every service before recreating
the ones that actually changed; the others are left untouched. Your data live
in the storage volume and survive the operation.
Then check that everything came back up, and reclaim the disk space taken by the replaced images:
For a single container started with docker run, the equivalent is to pull the
image, remove the old container and start it again with the same options (your
volume keeps the data):
Admin interface
happyDomain exposes administration commands through a Unix socket. The
container includes the hadmin wrapper:
hadmin is a thin wrapper around curl: start with the URL path, then add
any curl options after it.
Using a configuration file
Instead of environment variables, you can place a configuration file either in
/data/happydomain.conf (inside the data volume) or bind-mount it to
/etc/happydomain.conf: