Skip to content

Commit 96815ae

Browse files
author
Chris Snyder
committed
feat: Add ClamAV container with automatic config wiring for PHP 8.4 and 8.5
1 parent 2f7af4c commit 96815ae

15 files changed

Lines changed: 180 additions & 0 deletions

File tree

.github/workflows/build-clamav.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Build ClamAV image
2+
3+
on:
4+
release:
5+
types:
6+
- created
7+
pull_request:
8+
branches:
9+
- master
10+
paths:
11+
- clamav/**
12+
- .github/workflows/build-image.yml
13+
- .github/workflows/build-clamav.yml
14+
15+
jobs:
16+
build-clamav-image:
17+
name: Build ClamAV image
18+
uses: ./.github/workflows/build-image.yml
19+
with:
20+
image: clamav
21+
context: ./clamav
22+
push: ${{ github.event_name == 'release' }}
23+
secrets: inherit

.github/workflows/scan-images.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
fail-fast: true
1717
matrix:
1818
include:
19+
- image: clamav
1920
- image: mssql2017
2021
- image: mssql2019
2122
- image: mssql2022

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Although this project started as a development environment for Totara Learn it c
2323
* A [PHPUnit](https://phpunit.de/) and [Behat](http://behat.org/en/latest/) setup to run tests (including [Selenium](https://www.seleniumhq.org/))
2424
* A [MailDev](https://github.com/maildev/maildev?tab=readme-ov-file#maildev) instance to view sent emails
2525
* [Redis](https://redis.io/) for caching and/or session handling
26+
* [ClamAV](https://www.clamav.net/) for antivirus scanning, wired up automatically on PHP 8.4 and 8.5
2627
* [XHProf](https://github.com/tideways/php-xhprof-extension) for profiling
2728
* [XDebug](https://xdebug.org/) installed, ready for debugging with your favorite IDE
2829
* [Excimer](https://www.mediawiki.org/wiki/Excimer) installed, for discovering performance problems

bin/tdocker

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ source "$project_path/tools/check_for_update.sh"
1111
files=(
1212
"docker-compose.yml"
1313
"compose/apache.yml"
14+
"compose/clamav.yml"
1415
"compose/mariadb.yml"
1516
"compose/mssql.yml"
1617
"compose/mysql.yml"

clamav/Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM alpine:3.21
2+
3+
ARG TIME_ZONE=Pacific/Auckland
4+
5+
RUN apk add --no-cache \
6+
clamav \
7+
clamav-daemon \
8+
clamav-libunrar \
9+
freshclam \
10+
tzdata \
11+
&& ln -fs /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime \
12+
&& mkdir -p /run/clamav /var/lib/clamav
13+
14+
COPY config/clamd.conf /etc/clamav/clamd.conf
15+
COPY config/freshclam.conf /etc/clamav/freshclam.conf
16+
COPY entrypoint.sh /entrypoint.sh
17+
18+
RUN chmod +x /entrypoint.sh
19+
20+
# clamd listens on a unix socket shared with the PHP containers. TCP is for ad-hoc debugging.
21+
EXPOSE 3310
22+
23+
ENTRYPOINT ["/entrypoint.sh"]

clamav/config/clamd.conf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# docker-dev ClamAV daemon configuration.
2+
3+
# No LogFile - clamav refuses /dev/stdout as a log target ("Symbolic link loop"), and with
4+
# Foreground set it logs to stdout regardless, which is what docker wants.
5+
LogTime yes
6+
Foreground yes
7+
PidFile /run/clamav/clamd.pid
8+
DatabaseDirectory /var/lib/clamav
9+
10+
# Unix socket, shared with the PHP containers via the clamav-socket volume.
11+
# The PHP containers run clamdscan with --fdpass, which passes the file descriptor over this
12+
# socket, so clamd never needs to see the scanned file's path or have permission to read it.
13+
# Mode 0666 so that www-data in the PHP containers can connect.
14+
LocalSocket /run/clamav/clamd.sock
15+
LocalSocketMode 0666
16+
17+
# TCP is exposed for ad-hoc debugging only - the healthcheck uses the unix socket above. Totara
18+
# cannot use it either: antivirus_clamav's scanner::is_configured() returns false for the
19+
# tcpsocket running method, so a TCP-configured plugin is silently never invoked.
20+
TCPSocket 3310
21+
TCPAddr 0.0.0.0
22+
23+
MaxThreads 4
24+
25+
# Must stay above upload_max_filesize in php/config/php.ini.
26+
StreamMaxLength 100M

clamav/config/freshclam.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# docker-dev freshclam configuration.
2+
# The entrypoint runs freshclam once when the signature database is empty. The database lives in
3+
# the clamav-data volume, so this only downloads on first start.
4+
5+
DatabaseDirectory /var/lib/clamav
6+
# No UpdateLogFile, for the same reason as clamd.conf - the entrypoint passes --stdout instead.
7+
LogTime yes
8+
DatabaseMirror database.clamav.net
9+
Checks 1

clamav/entrypoint.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/sh
2+
set -e
3+
4+
# The clamav-socket and clamav-data volumes are owned by root when first created, but clamd and
5+
# freshclam both drop privileges to the clamav user, so hand them over.
6+
chown -R clamav:clamav /run/clamav /var/lib/clamav
7+
8+
# Only download signatures when we don't already have them - the clamav-data volume persists them
9+
# between runs, so this normally happens once per machine.
10+
if ! ls /var/lib/clamav/*.cvd /var/lib/clamav/*.cld >/dev/null 2>&1; then
11+
echo "clamav: no signature database found, running freshclam (this takes a few minutes)"
12+
freshclam --stdout || echo "clamav: freshclam failed, clamd will not start until signatures are available" >&2
13+
fi
14+
15+
exec clamd

compose/build.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
services:
2+
clamav:
3+
build:
4+
context: ./clamav
5+
args:
6+
TIME_ZONE: ${TIME_ZONE}
7+
28
mssql2017:
39
build:
410
context: ./mssql

compose/clamav.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
x-healthcheck-template: &clamav-healthcheck
2+
healthcheck:
3+
# clamd answers PING with PONG once it has finished loading its signatures. clamdscan reads
4+
# LocalSocket from clamd.conf, so this also proves the unix socket the PHP containers use is
5+
# actually accepting connections.
6+
test: ["CMD", "clamdscan", "--ping", "1"]
7+
interval: 10s
8+
timeout: 5s
9+
retries: 5
10+
# Loading the signature database takes around a minute, and the first ever start also has to
11+
# download it.
12+
start_period: 300s
13+
14+
services:
15+
16+
clamav:
17+
<<: *clamav-healthcheck
18+
image: ghcr.io/totara/docker-dev-clamav
19+
container_name: totara_clamav
20+
restart: ${RESTART_POLICY:-no}
21+
environment:
22+
TZ: ${TIME_ZONE}
23+
volumes:
24+
# Shared with the PHP 8.4/8.5 containers so clamdscan can reach clamd.
25+
- clamav-socket:/run/clamav
26+
# Persists the signature database so freshclam only downloads it on first start.
27+
- clamav-data:/var/lib/clamav
28+
networks:
29+
- totara
30+
31+
volumes:
32+
clamav-socket:
33+
clamav-data:

0 commit comments

Comments
 (0)