Scanning uploads for viruses

A ClamAV clamd daemon can scan attachments before they are stored. Off by default; to turn it on:

.env
COMPOSE_PROFILES=clamav
CLAMAV_HOST=clamav
  • docker-compose.prod.yml ships a clamav service behind the clamav profile, never reachable from the host.
  • It shares only the internal Docker network with app, not the proxy network, so nginx cannot reach it either.
  • Signature updates need outbound internet access, unlike the rest of the stack, so clamav gets its own egress network.
  • It needs roughly 1.5 GB RAM for the loaded signature database.

Scanning is fail-closed. With CLAMAV_HOST set, an upload is refused whenever clamd is unreachable or times out, exactly as if it were infected: nothing is ever stored unscanned. The whistleblower sees a generic "try again in a few minutes"; no file name, size or content reaches the log.

The Helm chart ships no clamav pod; the Compose profile has no Kubernetes equivalent. Setting config.clamavHost in values.yaml turns on the fail-closed behaviour for every upload: an unreachable clamd means refused, not skipped. Point it at a clamd you run and reach from the cluster, as its own Deployment and Service or an external instance. Leave it empty to keep scanning off.

Variable Description
CLAMAV_HOST Optional Hostname of the clamd daemon. Empty disables scanning entirely — no connection is ever made.
CLAMAV_PORT Optional clamd's TCP port. Default: 3310
CLAMAV_TIMEOUT_SECONDS Optional Connect and reply timeout for one scan. Exceeding it refuses the upload (fail closed). Default: 30

Edit this page on GitHub