build(infra): run ClamAV in compose and on the cluster (closes #191) #193
@@ -333,7 +333,7 @@ jobs:
|
||||
# Log dump must precede teardown (which removes the containers).
|
||||
- name: Dump container logs on failure
|
||||
if: failure()
|
||||
run: docker compose -f infra/docker-compose.yml logs --no-color --tail=100 oz-init openzaak nrc-init nrc-web nrc-celery nrc-beat flowable-db flowable-rest flowable-init keycloak acl bff domain projection-db event-subscriber projection-api self-service openbaar behandel beheer objecttypen-db objecttypen-redis objecttypen-init objecttypen objecten-db objecten-redis objecten-init objecten objecten-celery registerrecord-init tempo prometheus grafana 2>&1 || true
|
||||
run: docker compose -f infra/docker-compose.yml logs --no-color --tail=100 oz-init openzaak nrc-init nrc-web nrc-celery nrc-beat flowable-db flowable-rest flowable-init keycloak acl bff domain projection-db event-subscriber projection-api self-service openbaar behandel beheer objecttypen-db objecttypen-redis objecttypen-init objecttypen objecten-db objecten-redis objecten-init objecten objecten-celery registerrecord-init clamav tempo prometheus grafana 2>&1 || true
|
||||
- name: Tear down
|
||||
if: always()
|
||||
run: make down
|
||||
|
||||
@@ -10,7 +10,7 @@ COMPOSE := infra/docker-compose.yml
|
||||
# Long-running services with a healthcheck — the smoke polls these for readiness
|
||||
# (infra/wait-healthy.sh). One-shot init jobs (oz-init, nrc-init, flowable-init)
|
||||
# are not polled; they only need to have run. See docs/runbooks/gitea-actions-gotchas.md.
|
||||
WAIT_SVCS := openzaak nrc-web acl bff domain event-subscriber projection-api self-service openbaar behandel beheer objecttypen objecten
|
||||
WAIT_SVCS := openzaak nrc-web acl bff domain event-subscriber projection-api self-service openbaar behandel beheer objecttypen objecten clamav
|
||||
# Config files (OpenZaak data.yaml, Keycloak realms, Flowable BPMN) are streamed
|
||||
# into external named volumes via `docker cp` (infra/seed-config.sh) instead of
|
||||
# bind-mounted, because bind mounts don't reach sibling containers on the
|
||||
|
||||
@@ -785,6 +785,26 @@ services:
|
||||
condition: service_completed_successfully
|
||||
networks: [cg]
|
||||
|
||||
# ClamAV daemon (S-28, ADR-0036): the domain scans uploaded diplomas over clamd's INSTREAM
|
||||
# protocol on :3310 before they reach OpenZaak (S-29). The first start downloads ~300 MB of
|
||||
# signatures with freshclam; the volume keeps them across restarts. clamd holds them in memory
|
||||
# (~1.2 GB), and a reload would briefly hold two copies — ConcurrentDatabaseReload off prevents
|
||||
# that, at the cost of clamd pausing scans during a signature reload.
|
||||
clamav:
|
||||
image: docker.io/clamav/clamav:1.4.6
|
||||
environment:
|
||||
CLAMD_CONF_ConcurrentDatabaseReload: "no"
|
||||
# The image's own healthcheck (clamdcheck.sh: PING → PONG) polls every 30s; poll faster so
|
||||
# wait-healthy sees it as soon as the signatures are loaded.
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "clamdcheck.sh"]
|
||||
interval: 5s
|
||||
start_period: 360s
|
||||
mem_limit: 2g
|
||||
volumes:
|
||||
- clamav-db:/var/lib/clamav
|
||||
networks: [cg]
|
||||
|
||||
# ── Observability backplane (S-16a, ADR-0023) ──────────────────────────────
|
||||
# Grafana-native stack: Tempo ingests OTLP traces (the .NET services export
|
||||
# straight to it — no collector hop, S-16b), Prometheus scrapes service
|
||||
@@ -836,6 +856,7 @@ volumes:
|
||||
projection-db:
|
||||
objecttypen-db:
|
||||
objecten-db:
|
||||
clamav-db:
|
||||
# Config volumes — created and populated out-of-band by infra/seed-config.sh
|
||||
# (docker cp), because bind mounts don't reach sibling containers on the CI
|
||||
# runner. `external` keeps the names deterministic; the seed step manages them.
|
||||
|
||||
@@ -588,6 +588,24 @@ workloads:
|
||||
envFrom: [objecten]
|
||||
waitFor: [objecten-db:5432, objecten-redis:6379]
|
||||
|
||||
# ── ClamAV (S-28, ADR-0036) ─────────────────────────────────────────────────
|
||||
# The domain scans uploaded diplomas over clamd's INSTREAM protocol (S-29).
|
||||
# First start pulls ~300 MB of signatures, so the node needs outbound internet
|
||||
# (like seed-zaaktype); the data volume keeps them when persistence is on.
|
||||
clamav:
|
||||
image: docker.io/clamav/clamav:1.4.6
|
||||
env:
|
||||
CLAMD_CONF_ConcurrentDatabaseReload: "no"
|
||||
ports: [{ name: clamd, port: 3310 }]
|
||||
data: { mountPath: /var/lib/clamav, size: 1Gi }
|
||||
probe:
|
||||
exec: { command: [clamdcheck.sh] }
|
||||
periodSeconds: 5
|
||||
failureThreshold: 72
|
||||
resources:
|
||||
requests: { memory: 1200Mi }
|
||||
limits: { memory: 2Gi }
|
||||
|
||||
# ── Bootstrap the flow, like the local compose stack does (S-B04, ADR-0020) ──
|
||||
# Seeds + publishes the BIG zaaktype through the same FQDN the ACL uses, so the
|
||||
# server-assigned URLs are host-consistent. The ACL then resolves them by
|
||||
|
||||
Reference in New Issue
Block a user