fix(deploy): il gioco non si collegava — /ws riscritto da try_files e tsx fuori dal PATH #1
Loading…
Reference in a new issue
No description provided.
Delete branch "a.balena/sparatutto:fix/produzione-ws-e-avvio"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Il deploy Coolify di
sparatutto.lascuolaopensource.orgrispondeva 502, e una volta tolto di mezzo il 502 il gioco comunque non si collegava. Sono tre guasti sovrapposti: uno era nell'infrastruttura (già sistemato, fuori da questa PR), due sono qui.1.
/wsnon arrivava mai al server di giocoNel
Caddyfileil proxy del WebSocket e il fallback SPA stavano piatti nello stesso blocco:Caddy però non esegue le direttive nell'ordine in cui le scrivi: le riordina, e in quell'ordine
try_filessta fra le manipolazioni della richiesta, molto prima direverse_proxy. Siccome/wsnon è un file dentroclient/dist,try_fileslo riscriveva in/index.html; a quel punto il matcherpath /wsnon faceva più match e il proxy non scattava mai.Verificato con un handshake vero contro il container in produzione:
Ora i due percorsi stanno in due
handledistinti, mutuamente esclusivi e valutati nell'ordine scritto — che è poi la stessa ricetta già scritta indocs/HOSTING.md:174. Il matcher resta/wsesatto come prima: cambia l'ordine, non cosa viene intercettato.2. Il server di gioco non è mai partito —
tsxnon è nel PATHNei log del container, dal primissimo avvio:
Il binario c'è ed è sano (
node_modules/.bin/tsx -> ../tsx/dist/cli.mjs, tsx v4.23.1), ma/app/node_modules/.binnon è nel PATH dinode:22-alpine: invocato nudo non viene trovato. Lo script ora si mette quella cartella nel PATH.Il guasto è rimasto invisibile per via di una corsa nel guardiano: era la subshell del server, morendo, a dover ammazzare Caddy con una
pkill, matsxmoriva prima che Caddy fosse partito e lapkillnon trovava nessuno. Caddy nasceva subito dopo, ilwaitnon tornava più e il container restavaUp— Coolify lo dava per sano mentre metà app era morta, e il sito serviva la home statica di un gioco a cui era impossibile connettersi. La ronda passa quindi al guscio principale: le subshell lasciano solo scritto chi è caduto e con che codice, il guscio aspetta quel certificato di morte e ammazza il superstite, che a quel punto esiste di sicuro.Come sono state verificate
Non a occhio: container usa-e-getta creato dalla stessa immagine di produzione, con dentro solo questi due file sostituiti, attaccato alla rete
coolifye interrogato dal proxy.E il guardiano in entrambi i versi: ammazzando il server il container esce
143scrivendoSPARA: e' caduto server (uscita 143), spengo il container.; ammazzando Caddy esce dichiarando l'altro caduto. Conrestart: unless-stopped(la policy che Coolify mette al container) un avvio a metà ora si vede subito invece di mascherarsi. Container di prova rimosso a fine verifica.3. Il 502 — non è in questa PR, era nel proxy
Per completezza, la causa del gateway error: sul proxy Caddy dell'host Coolify c'erano due definizioni dello stesso dominio, la label generata da Coolify (
reverse_proxy 10.0.1.10:80, giusta) e uno snippet scritto a mano in/data/coolify/proxy/caddy/dynamic/sparatutto.caddyche puntava areverse_proxy sparatutto:80. In questi casicaddy-docker-proxyscarta il blocco delle label ([ERROR] Removing invalid block: ambiguous site definition) e tiene lo snippet — il cui upstreamsparatuttoin Docker non risolve, perché l'unico alias di rete del container è<uuid>-<timestamp>. Da qui il 502, con il container invece perfettamente vivo.Lo snippet è stato spostato in
/data/coolify/proxy/caddy/sparatutto.caddy.disabled-20260829e il dominio è tornato a rispondere 200. Non va reintrodotto: le label di Coolify si aggiornano da sole a ogni deploy, lo snippet no.Dopo il merge serve un redeploy da Coolify perché i due file stanno dentro l'immagine.
In produzione il container e' sempre partito a meta'. Nei log, dal primo avvio: `avvia-produzione.sh: line 14: tsx: not found`. Il binario c'e' ed e' sano, ma sta in /app/node_modules/.bin, che non e' nel PATH dell'immagine node:22-alpine; invocato nudo non viene trovato. Lo script ora si mette quella cartella nel PATH. Il guasto e' rimasto invisibile per via di una corsa nel guardiano: era la subshell del server, morendo, a dover ammazzare Caddy con una pkill, ma tsx moriva prima che Caddy fosse partito e la pkill non trovava nessuno. Caddy nasceva subito dopo, il `wait` non tornava piu' e il container restava Up — Coolify lo dava per sano mentre meta' app era morta, e il sito serviva la home statica di un gioco a cui era impossibile connettersi. La ronda passa quindi al guscio principale: le subshell si limitano a lasciare scritto chi e' caduto e con che codice, il guscio aspetta quel certificato di morte e solo allora ammazza il superstite — che a quel punto esiste di sicuro. Verificato su un container usa-e-getta dalla stessa immagine di produzione: il server parte ("in ascolto su ws://0.0.0.0:8080"); ammazzando il server il container esce 143, ammazzando Caddy esce dichiarando il caduto. Con `restart: unless-stopped` un avvio a meta' ora si vede subito invece di mascherarsi. Co-Authored-By: Claude Opus 5 <[email protected]>