<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Giuseppe Viscomi</title>
    <description>The latest articles on DEV Community by Giuseppe Viscomi (@giuseppe_viscomi_171).</description>
    <link>https://dev.to/giuseppe_viscomi_171</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4124136%2F2f0a565f-b29b-4891-85be-9ef73fcb3dc0.png</url>
      <title>DEV Community: Giuseppe Viscomi</title>
      <link>https://dev.to/giuseppe_viscomi_171</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/giuseppe_viscomi_171"/>
    <language>en</language>
    <item>
      <title>xz: Failed to enable the sandbox — perché la build Docker fallisce solo sul server</title>
      <dc:creator>Giuseppe Viscomi</dc:creator>
      <pubDate>Mon, 14 Sep 2026 08:14:01 +0000</pubDate>
      <link>https://dev.to/giuseppe_viscomi_171/xz-failed-to-enable-the-sandbox-perche-la-build-docker-fallisce-solo-sul-server-1c0d</link>
      <guid>https://dev.to/giuseppe_viscomi_171/xz-failed-to-enable-the-sandbox-perche-la-build-docker-fallisce-solo-sul-server-1c0d</guid>
      <description>&lt;p&gt;Se sei arrivato qui da una ricerca, probabilmente hai davanti questo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;=&amp;gt; ERROR [3/5] RUN docker-php-ext-install mysqli pdo_mysql gd zip

xz: (stdin): Failed to enable the sandbox
tar: Child returned status 1
tar: Error is not recoverable: exiting now
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La build fallisce sempre nello stesso punto, in modo riproducibile. E la&lt;br&gt;
stessa identica immagine sul tuo portatile si costruisce senza problemi.&lt;/p&gt;
&lt;h2&gt;
  
  
  La soluzione, subito
&lt;/h2&gt;

&lt;p&gt;Se ti serve solo sbloccare la build, sono tre passaggi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Scarica il profilo seccomp predefinito della tua versione di Docker e&lt;br&gt;
salvalo come nuovo file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp &lt;/span&gt;default-seccomp.json &lt;span class="se"&gt;\&lt;/span&gt;
        /etc/docker/seccomp-nolandlock.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Dentro, nell'elenco delle regole, aggiungi questo blocco:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"names"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"landlock_create_ruleset"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"landlock_add_rule"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"landlock_restrict_self"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SCMP_ACT_ERRNO"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"errnoRet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Poi rendilo predefinito in &lt;code&gt;/etc/docker/daemon.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"seccomp-profile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/etc/docker/seccomp-nolandlock.json"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; Ed ecco il passaggio che quasi tutti saltano — senza, la build&lt;br&gt;
fallisce ancora e sembra che la soluzione non funzioni:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;DOCKER_BUILDKIT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0 docker compose build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il motivo di quest'ultimo comando è nella sezione finale, ed è la parte che&lt;br&gt;
conviene leggere: spiega perché i primi due passaggi da soli non bastano.&lt;/p&gt;
&lt;h2&gt;
  
  
  Perché succede
&lt;/h2&gt;

&lt;p&gt;Il messaggio va letto alla lettera. Non dice che l'archivio è corrotto. Dice&lt;br&gt;
che &lt;code&gt;xz&lt;/code&gt; &lt;strong&gt;non è riuscito ad attivare la sandbox&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Le versioni recenti di &lt;code&gt;xz&lt;/code&gt; si auto-confinano prima di elaborare dati non&lt;br&gt;
fidati: dichiarano al kernel "d'ora in poi non voglio più poter aprire file&lt;br&gt;
né usare la rete", così una vulnerabilità nel decompressore non diventa una&lt;br&gt;
compromissione della macchina. Su Linux questo si appoggia a &lt;strong&gt;Landlock&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Qui si incastrano tre pezzi che, presi singolarmente, sono tutti corretti.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Il kernel della distribuzione server.&lt;/strong&gt; Se stai usando RHEL, CentOS Stream,&lt;br&gt;
Rocky o AlmaLinux, il kernel ha una numerazione apparentemente vecchia ma è&lt;br&gt;
pesantemente modificato dal vendor. Espone i syscall di Landlock, ma con una&lt;br&gt;
ABI più arcaica di quella che &lt;code&gt;xz&lt;/code&gt; recente si aspetta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;L'immagine.&lt;/strong&gt; Le immagini ufficiali PHP sono basate su Debian recente, e&lt;br&gt;
contengono un &lt;code&gt;xz&lt;/code&gt; moderno che quella ABI antica non sa gestire.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Il profilo seccomp di Docker.&lt;/strong&gt; Filtra i syscall che un container può&lt;br&gt;
invocare. Quando ne incontra uno che non conosce, non risponde "non&lt;br&gt;
supportato": risponde &lt;strong&gt;errore di permesso&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ed è il terzo punto la chiave.&lt;/p&gt;

&lt;p&gt;Se &lt;code&gt;xz&lt;/code&gt; ricevesse "questa funzionalità non esiste" (&lt;code&gt;ENOSYS&lt;/code&gt;), si&lt;br&gt;
comporterebbe bene: rinuncerebbe alla sandbox e proseguirebbe. È il&lt;br&gt;
comportamento previsto sui kernel senza Landlock. Ma riceve &lt;code&gt;EACCES&lt;/code&gt;, che&lt;br&gt;
significa una cosa diversa — &lt;em&gt;la funzionalità c'è ma non puoi usarla&lt;/em&gt; — e di&lt;br&gt;
fronte a quello fa la scelta prudente: si rifiuta di lavorare senza&lt;br&gt;
protezione ed esce con errore.&lt;/p&gt;

&lt;p&gt;Il programma sta funzionando esattamente come progettato. Sta rifiutando di&lt;br&gt;
abbassare le proprie difese. Solo che nessuno lo sta attaccando: sta&lt;br&gt;
decomprimendo il sorgente di un'estensione PHP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nessuno dei tre componenti è rotto. È rotta la loro combinazione.&lt;/strong&gt; Ed è&lt;br&gt;
per questo che cercando il messaggio d'errore si trova poco: chi ha quel&lt;br&gt;
kernel di solito non usa quell'immagine, e chi usa quell'immagine di solito&lt;br&gt;
ha un kernel recente.&lt;/p&gt;
&lt;h2&gt;
  
  
  Perché serve anche DOCKER_BUILDKIT=0
&lt;/h2&gt;

&lt;p&gt;Docker ha due motori di costruzione. Quello moderno, attivo di default nelle&lt;br&gt;
versioni recenti, &lt;strong&gt;non esegue i passaggi di build sotto il profilo seccomp&lt;br&gt;
del demone&lt;/strong&gt;: gestisce il proprio isolamento in autonomia.&lt;/p&gt;

&lt;p&gt;Significa che il profilo che hai appena configurato vale per i container in&lt;br&gt;
esecuzione, ma la build gli passa accanto. È il momento in cui si conclude&lt;br&gt;
che la diagnosi era sbagliata — e invece manca solo di chiedere il motore&lt;br&gt;
classico.&lt;/p&gt;

&lt;p&gt;Conviene renderlo permanente per l'utente che costruisce le immagini, perché&lt;br&gt;
prima o poi qualcuno lancerà il comando senza la variabile e si troverà&lt;br&gt;
davanti un errore che nessuno ricorda più:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export DOCKER_BUILDKIT=0'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Una nota di onestà
&lt;/h2&gt;

&lt;p&gt;Stiamo disattivando un irrobustimento di sicurezza.&lt;/p&gt;

&lt;p&gt;Il rischio reale è modesto: Landlock su quel kernel non era comunque&lt;br&gt;
utilizzabile, quindi non stiamo rinunciando a una protezione che avevamo —&lt;br&gt;
stiamo smettendo di &lt;em&gt;fingere&lt;/em&gt; di averla. Ma è una rinuncia, non un fix, e va&lt;br&gt;
scritta nella documentazione dell'infrastruttura.&lt;/p&gt;

&lt;p&gt;Quando il server passerà a un kernel più recente, il profilo va rimosso e la&lt;br&gt;
build riprovata senza. Le soluzioni di questo tipo hanno una scadenza, e&lt;br&gt;
l'unico modo perché non diventino debito permanente è annotarla.&lt;/p&gt;

&lt;h2&gt;
  
  
  La lezione che vale oltre questo caso
&lt;/h2&gt;

&lt;p&gt;Io ci ho perso tre ore. Ho svuotato la cache di build, controllato lo spazio&lt;br&gt;
su disco, cambiato versione di PHP, messo SELinux in permissive. Tutti&lt;br&gt;
tentativi sensati, tutti inutili.&lt;/p&gt;

&lt;p&gt;L'errore di metodo era sempre lo stesso: cercavo la causa &lt;strong&gt;dentro il&lt;br&gt;
container&lt;/strong&gt;. Ma il container era la stessa identica immagine che in locale&lt;br&gt;
funzionava. L'unica variabile cambiata era la macchina sotto.&lt;/p&gt;

&lt;p&gt;Da lì una regola che ho adottato. Quando una build fallisce solo su una&lt;br&gt;
macchina, la prima domanda non è "cos'ha di sbagliato il Dockerfile", ma:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Che cosa di questa macchina è visibile dall'interno del container?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La lista è corta — il kernel, che è condiviso e &lt;em&gt;non&lt;/em&gt; fa parte dell'immagine;&lt;br&gt;
i filtri sui syscall; i moduli di sicurezza della distribuzione;&lt;br&gt;
l'architettura del processore. Percorrerla richiede dieci minuti.&lt;/p&gt;

&lt;p&gt;E un corollario che vale ben oltre Docker: &lt;strong&gt;quando un programma rifiuta di&lt;br&gt;
funzionare per motivi di sicurezza, la domanda giusta non è come zittirlo, ma&lt;br&gt;
quale informazione sbagliata gli sta arrivando.&lt;/strong&gt; Qui il programma era&lt;br&gt;
corretto e la risposta che riceveva era falsa. Aggirare il controllo avrebbe&lt;br&gt;
funzionato per caso; correggere la risposta ha funzionato per la ragione&lt;br&gt;
giusta.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Questo è uno dei problemi che ho incontrato containerizzando 61 progetti PHP&lt;br&gt;
legacy e 113 database, senza riscrivere una riga di applicazione. Ne ho fatto&lt;br&gt;
un libro — &lt;a href="https://amzn.to/4dzZeoS" rel="noopener noreferrer"&gt;Docker per PHP legacy&lt;/a&gt; — costruito tutto così: il sintomo,&lt;br&gt;
i tentativi sbagliati, la causa vera, e cosa resta valido oltre il caso&lt;br&gt;
specifico.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>linux</category>
      <category>php</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
