This repository provides a 2-stage Docker build on Alpine Linux:
updaterstage installs ClamAV and refreshes signatures withfreshclam.scannerstage runsclamscanagainst a file or directory provided as an argument or via stdin.
Wrapper script:
./scan.sh --update
./scan.sh /path/to/file
./scan.sh /path/to/directory
./scan.sh --watch /path/to/directoryYou can override image names if needed:
IMAGE_NAME=my-clamav UPDATER_IMAGE_NAME=my-clamav-updater ./scan.sh --update
IMAGE_NAME=my-clamav ./scan.sh /path/to/file
IMAGE_NAME=my-clamav ./scan.sh --watch /path/to/directoryWatch mode notes:
--watchuses ClamAV's native on-access watcher (clamonacc) inside Docker.- Infected files are moved to
./.quarantine(created automatically if missing). --watchrequires a directory path (single-file watch is not supported).--watchrequires a Linux host for native event watching.
Direct Docker usage:
Scan a mounted file or directory (argument mode):
docker run --rm -v /host/data:/scan clamav /scan/path/to/file-or-dirExample matching your requested form (path inside container):
docker run clamav /path/to/fileScan target path via stdin:
echo /scan/path/to/file-or-dir | docker run --rm -i -v /host/data:/scan clamavclamscan output is printed directly, followed by one explicit status line:
STATUS: CLEANSTATUS: INFECTEDSTATUS: ERROR
Container exit codes follow clamscan semantics:
0: no infection found1: infection found2: error
Step 1 (refresh ClamAV + signatures):
TOKEN="$(date -u +%Y%m%d%H%M%S)"
docker build \
--pull \
--no-cache \
--target updater \
--build-arg CACHE_BUST="${TOKEN}" \
-t clamav-updater .Step 2 (build runnable scanner image from refreshed stage):
docker build \
--pull \
--no-cache \
--build-arg CACHE_BUST="${TOKEN}" \
-t clamav .Notes:
CACHE_BUSTintentionally breaks build cache for the updater stage so reruns always refresh packages/signatures.- Use the same
TOKENfor both steps so the scanner image is built from the same refreshed signature snapshot. - This makes stage 1 safe and repeatable for cron-based refresh jobs.
scan.sh --updateadditionally builds with--pull --no-cacheand the Dockerfile runsapk update && apk upgrade, so Alpine base/packages are refreshed each update run.