#!/bin/sh # Der Tunnel und der Arbeiter, die sich einen Container teilen — aber nicht # mehr ein Schicksal. # # Bis hierher war `php artisan queue:work` der Prozess 1 dieses Containers. # Damit hing wg0 an seinem Leben: jedes Mal, wenn der Arbeiter endete, endete # der Container, und mit ihm der Netz-Namensraum, in dem der Tunnel steht. # # Ein Arbeiter endet oefter, als man denkt. `--timeout=2100` beendet ihn, wenn # ein Provisionierungs-Schritt zu lange braucht. Ein fataler Fehler beendet ihn. # Ein ueberschrittenes Speicherlimit beendet ihn. `queue:restart` beendet ihn # absichtlich. In allen vier Faellen fielen bisher saemtliche WireGuard-Sitzungen # mit — die des Betreibers am Telefon genauso wie die jedes Hosts. Von aussen sah # das aus wie „das VPN ist unzuverlaessig", und die Ursache stand in einer Zeile # docker-compose.yml, die von Warteschlangen handelt. # # Deshalb: wg0 einmal hochziehen, und danach den Arbeiter in einer Schleife # halten. Faellt er, kommt er wieder — der Tunnel merkt nichts davon. # # Der Container endet dann nur noch, wenn Docker ihn beendet. Das ist Absicht: # ein Arbeiter, der nicht startet, ist ein Fall fuers Protokoll, kein Grund, # jedem Host die Verbindung abzuschneiden. set -u wg-quick up wg0 2>/dev/null || true # SIGTERM sauber weiterreichen: sonst wartet `docker compose stop` zehn Sekunden # und schlaegt dann mit SIGKILL zu — mitten in einem Provisionierungs-Schritt. child='' stop() { [ -n "$child" ] && kill -TERM "$child" 2>/dev/null exit 0 } trap stop TERM INT while true; do php artisan queue:work provisioning \ --queue=provisioning \ --tries=1 \ --timeout=2100 \ --sleep=3 & child=$! wait "$child" code=$? # Ins Protokoll, nicht ins Nichts: ein Arbeiter, der staendig neu startet, # ist ein eigenes Problem — es soll nur nicht mehr das Problem des Tunnels # sein. echo "[provisioning] Arbeiter beendet (Code ${code}) — wg0 bleibt oben, Neustart in 2 s" >&2 sleep 2 done