[Unit] Description=DWS Stapel-Worker (Batch) - Instanz %i Documentation=file:/var/www/html/dws/batch/README.md After=network.target mysql.service redis-server.service # Kein Requires: faellt Redis aus, arbeitet der Worker im Notbetrieb weiter (Treiber dbpoll), # und ein fehlendes Redis darf den Dienst nicht am Starten hindern. Wants=redis-server.service [Service] Type=simple User=www-data Group=www-data # Pfad zur batchworker.php der Umgebung + Servername fuer die CLI (dort gibt es kein $_SERVER) EnvironmentFile=/var/www/html/dws/batch/instances/%i.env # Die Umgebung (develop/productive) ergibt sich allein aus dem Ablageort der batchworker.php - # daraus leitet __rootloader.php Datenbank, .env und den Redis-Schluesselpraefix ab. WorkingDirectory=/var/www/html/dws/%i/v1 ExecStart=/usr/bin/php ${DWS_BATCH_WORKER_SCRIPT} --daemon -v # Der Worker soll eine laufende Position zu Ende bringen duerfen, bevor er stirbt: ein hartes SIGKILL # mittendrin hinterlaesst einen Auftrag in RUNNING, den erst der Reconciler nach 15 Minuten zurueckholt. KillSignal=SIGTERM TimeoutStopSec=90 Restart=always RestartSec=5 StandardOutput=journal StandardError=journal SyslogIdentifier=dws-batchworker-%i NoNewPrivileges=true # PrivateTmp waere hier falsch: der Worker liest und schreibt unter .private/batch/ im DocumentRoot, # nicht in /tmp - aber ein eigener /tmp schadet auch nicht und schliesst eine Angriffsflaeche. PrivateTmp=true # ProtectSystem=full macht /usr und /etc schreibgeschuetzt; /var/www bleibt beschreibbar, was der # Worker fuer die Job-Ordner braucht. ProtectSystem=full ProtectHome=true [Install] WantedBy=multi-user.target