Files
ignacionelson d11bda094b Say out loud when scanning has quietly stopped protecting anything
The defaults let files through when the scanner cannot answer, so an
installation whose scanner died looks, from every screen anybody uses,
exactly like one that is working. Three places now say otherwise.

`projectsend:status` gains a `scanning` block: whether it is on, whether
it is managed, whether the scanner answers right now, the engine and
how old its definitions are, what is waiting, what is quarantined, and
how many files went out unscanned in the last 24 hours. Absent, null and
zero stay distinct — `reachable: null` means there is nothing to reach,
`false` means it should be answering and is not. The scans queue is
reported beside the other two.

The dashboard's System card carries the same warning for whoever is
actually looking at a screen, and says nothing at all while scanning is
healthy or switched off.

Docker gets the scanner as an opt-in profile — `--profile scanner` — in
both the development compose file and the published example, with a
clamd.conf whose Alert* options are what make an encrypted archive come
back as "could not scan" instead of "OK". No published ports: clamd has
no authentication and the file crosses that socket in the clear. Both
images also run a worker for the scans queue.

The dashboard test caught a 500 before it shipped: a nullable return
written as `array`.
2026-09-16 14:39:06 -03:00

90 lines
2.8 KiB
Plaintext

; Four processes, one container. The dev stack runs these as separate
; compose services; an official image people `docker run` has to carry them
; itself, or scheduled work and queued jobs silently never happen.
;
; Everything logs to stdout/stderr so `docker logs` is the single place to
; look — no log files inside the container to discover and rotate.
[supervisord]
nodaemon=true
user=root
logfile=/dev/null
logfile_maxbytes=0
pidfile=/run/supervisord.pid
[program:php-fpm]
command=php-fpm --nodaemonize
autostart=true
autorestart=true
priority=10
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:nginx]
command=nginx -g "daemon off;"
autostart=true
autorestart=true
priority=20
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
; --max-time recycles the worker hourly. Long-lived PHP workers accumulate
; state, and a worker started before a deploy keeps running the old code
; until it exits; an hour bounds both without thrashing.
[program:queue]
command=su-exec www-data php /var/www/html/artisan queue:work --queue=default --max-time=3600 --tries=3
autostart=true
autorestart=true
priority=30
stopwaitsecs=3630
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
; Zip builds get their own worker. BuildZipDownloadJob allows itself an
; hour, and on the shared queue one large archive holds up every
; notification email queued behind it. --tries=1 matches the job, which
; records its own failure rather than being retried.
[program:queue-zips]
command=su-exec www-data php /var/www/html/artisan queue:work --queue=zips --max-time=3600 --tries=1
autostart=true
autorestart=true
priority=31
stopwaitsecs=3630
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
; Virus scans get their own worker, for the reason zips do: reading a 5 GB
; file to the scanner takes minutes, and on the shared queue it would sit
; in front of every notification email. Harmless on an installation with no
; scanner configured — the queue is simply empty.
[program:queue-scans]
command=su-exec www-data php /var/www/html/artisan queue:work --queue=scans --max-time=3600 --tries=1
autostart=true
autorestart=true
priority=32
stopwaitsecs=3630
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
; schedule:work is the long-running equivalent of a per-minute cron entry,
; which is what a container should use — there is no crond here.
[program:scheduler]
command=su-exec www-data php /var/www/html/artisan schedule:work
autostart=true
autorestart=true
priority=40
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0