DokuWiki has a feature called “farming” — running multiple independent wiki instances from a single installation. Each instance (called an “animal”) gets its own content, configuration, and ACL, but shares the same codebase. It’s efficient and surprisingly elegant.

We run a DokuWiki farm in a single Docker container serving several wikis, each on its own hostname.

How farming works

The secret is preload.php — a file that DokuWiki loads before anything else. It inspects the incoming hostname and sets the DOKU_CONF constant to point to the appropriate animal’s configuration directory. Each animal is essentially a separate wiki that happens to share the same PHP code.

The configuration cascade is:

  1. DokuWiki defaults
  2. Farm-level local.php (shared settings)
  3. Animal-level conf/local.php (per-wiki overrides)

Users and ACLs can be shared (farm-level users.auth.php) or per-animal. We share the user database but keep ACLs separate — different wikis have different access rules. Some are public-read, one requires login for everything.

The Docker mount puzzle

DokuWiki’s plugin system creates an interesting Docker problem. If you bind-mount your own plugins directory, it replaces the container’s built-in plugins entirely. That means you need to manually include built-in plugins (like authplain for local user authentication) in your mounted directory.

The solution is to mount a custom plugins directory that contains both your custom plugins and copies of the built-in ones you need. It’s a one-time setup cost, but it’s the kind of thing that causes a mysterious “no authentication available” error if you forget.

Custom plugins in a containerized world

One of the wikis uses custom plugins for specialized content — buttons that pull images from a mounted directory, and a math rendering plugin. The math plugin needs a PHP extension (tokenizer) that isn’t included in the base image.

The container uses a LinuxServer.io image, which supports custom initialization scripts. A script in custom-cont-init.d installs the missing PHP extension on every container start. It’s not elegant — it reinstalls on every restart — but it’s persistent and requires zero maintenance. The alternative (a custom Dockerfile) would mean managing image builds, which is more infrastructure for a wiki.

The template

All wikis share a custom template mounted read-only. The template strips DokuWiki’s default chrome to a minimum:

  • No footer
  • No page metadata (last modified, etc.)
  • Login/user tools hidden for anonymous visitors
  • Registration disabled

The goal is that the wiki looks like a simple documentation site, not a wiki. Visitors don’t need to know (or care) that there’s a wiki engine behind the pages.

What makes farming worthwhile

The alternative is running separate DokuWiki containers per wiki. That means separate images, separate updates, separate PHP processes. With farming, one container handles everything. Updates apply to all wikis at once. Memory usage is a single PHP-FPM pool instead of three.

The trade-off is complexity in the preload.php routing and the shared-vs-separate configuration dance. But once it’s set up, it’s genuinely low maintenance — which, for a wiki, is exactly the right property.