{"id":3,"date":"2026-01-15T20:47:00","date_gmt":"2026-01-15T20:47:00","guid":{"rendered":"https:\/\/rpi.temporiti.net\/wordpress\/blog\/sincronizzazione-file-decentralizzata-p2p\/"},"modified":"2026-05-30T14:05:19","modified_gmt":"2026-05-30T12:05:19","slug":"sincronizzazione-file-decentralizzata-p2p","status":"publish","type":"post","link":"https:\/\/rpi.temporiti.net\/wordpress\/?p=3","title":{"rendered":"Sincronizzazione file decentralizzata con Syncthing"},"content":{"rendered":"<p>Sincronizzare file fra macchine diverse senza affidarsi a un cloud di terzi \u00e8 una di quelle abitudini che mi hanno cambiato il modo di lavorare. Sulla scrivania ho un portatile Linux, in salotto un Mac mini dedicato al multimedia, in un angolo un paio di Raspberry Pi e su un provider cloud un piccolo server ARM su tier gratuito. Tenere allineata la cartella <code>~\/Documenti\/note\/<\/code> fra tutti questi posti, senza che nessuno legga i miei file, \u00e8 il caso d&#8217;uso perfetto per <a href=\"https:\/\/syncthing.net\/\">Syncthing<\/a>.<\/p>\n<h2>Installare<\/h2>\n<p>Su Debian e derivate, incluso Raspberry Pi OS, il pacchetto \u00e8 nel repo ufficiale. Sul portatile uso fish come shell, sui server bash di default:<\/p>\n<pre><code class=\"language-bash\">\nsudo apt update\nsudo apt install syncthing\n<\/code><\/pre>\n<p>Su Mac via Homebrew:<\/p>\n<pre><code class=\"language-bash\">\nbrew install syncthing\nbrew services start syncthing\n<\/code><\/pre>\n<p>Sui sistemi headless lo abilito come servizio utente, sostituendo <code>USERNAME<\/code> con il mio utente di servizio:<\/p>\n<pre><code class=\"language-bash\">\nsudo systemctl enable --now syncthing@USERNAME.service\n<\/code><\/pre>\n<p>Il demone parte su <code>127.0.0.1:8384<\/code> per la web UI e su TCP\/UDP 22000 per la sincronizzazione vera e propria. Se il server \u00e8 remoto, faccio tunnel SSH per arrivare alla UI invece di esporla in rete:<\/p>\n<pre><code class=\"language-bash\">\nssh -L 8384:127.0.0.1:8384 utente@host-remoto\n<\/code><\/pre>\n<p>E apro <code>http:\/\/127.0.0.1:8384<\/code> in locale. Esporre la web UI direttamente su internet \u00e8 una pessima idea: l&#8217;autenticazione di default \u00e8 basilare e da li si gestisce l&#8217;intera tailnet di file.<\/p>\n<h2>Aggiungere un dispositivo<\/h2>\n<p>Ogni nodo ha un Device ID lungo, generato alla prima esecuzione. Dalla web UI lo copio, sull&#8217;altro nodo apro &#8220;Add Remote Device&#8221; e lo incollo. Quando entrambi si vedono, posso condividere cartelle. Tre accortezze che applico sempre:<\/p>\n<p>1. <strong>Folder Type &#8220;Send &#038; Receive&#8221;<\/strong> sulla macchina principale, <strong>&#8220;Receive Only&#8221;<\/strong> sui Raspberry Pi: un errore su un Pi non torna a sporcarmi il master.<\/p>\n<p>2. <strong>Versioning &#8220;Staggered&#8221;<\/strong> con retention a 30 giorni: salva snapshot a intervalli crescenti e mi permette di recuperare un file modificato per sbaglio anche tre settimane dopo.<\/p>\n<p>3. <strong>Ignore patterns<\/strong> per <code>.DS_Store<\/code>, <code>.git\/<\/code>, <code>node_modules\/<\/code> e cartelle di cache: senza, Syncthing si mangia banda dietro a robaccia.<\/p>\n<h2>Topologia e routing<\/h2>\n<p>Per ridurre il traffico relay e tenere la sincronizzazione veloce, configuro un nodo come &#8220;Introducer&#8221; e abilito il discovery globale solo dove serve. Sui server in cloud con IP pubblico aggiungo l&#8217;hint statico nel device address: invece di <code>dynamic<\/code> metto <code>tcp:\/\/203.0.113.10:22000<\/code>. In questo modo il NAT traversal \u00e8 immediato e non serve passare dai relay pubblici Syncthing.<\/p>\n<p>Le porte 22000\/tcp e 22000\/udp sui server vanno aperte nel security group o sull&#8217;host firewall:<\/p>\n<pre><code class=\"language-bash\">\nsudo ufw allow 22000\/tcp\nsudo ufw allow 22000\/udp\n<\/code><\/pre>\n<h2>Un caso reale<\/h2>\n<p>Una mattina, intorno alle 9:30, stavo lavorando su un Raspberry Pi della stanza-studio quando ho dovuto spostarmi al portatile per un ticket urgente. Apro il laptop e in venti secondi la cartella note \u00e8 gi\u00e0 aggiornata con quello che avevo scritto sul Pi. Niente upload manuali, niente &#8220;lascia perdere, lo finisco poi&#8221;. Quattro ore dopo, al rientro, ho notato che un service di un host periferico aveva ricreato per errore qualche file dentro <code>node_modules<\/code> in una cartella condivisa per sbaglio: la <code>Receive Only<\/code> di quel nodo ha bloccato la propagazione, ho potuto fare cleanup centralmente senza rincorrere copie sporche su tre macchine.<\/p>\n<h2>Cosa funziona bene<\/h2>\n<p>La filosofia peer-to-peer mi piace: i file restano miei, cifrati in transito, e non c&#8217;\u00e8 nessun servizio centrale che vede i metadati. Lo Staggered Versioning mi ha salvato almeno tre volte da rm sbagliati. La UI \u00e8 chiara, lo stato di ogni cartella \u00e8 leggibile a colpo d&#8217;occhio.<\/p>\n<h2>Limiti<\/h2>\n<p>Per cartelle con tantissimi file piccoli (un cache di build, una libreria con migliaia di assets) Syncthing fatica e il CPU sul Raspberry Pi schizza. Per quei casi continuo a usare <code>rsync<\/code> puntuale o uno share NFS. Il primo handshake fra device dietro NAT a volte richiede un paio di minuti, soprattutto se la rete del provider cloud blocca certi flussi UDP.<\/p>\n<h2>In pratica<\/h2>\n<p>Syncthing \u00e8 diventato il livello di trasporto file dell&#8217;homelab: copre la mia esigenza di &#8220;stessi file, ovunque&#8221;, senza che nessuno si metta in mezzo. Lo accoppio con backup a freddo per il disaster recovery e con un object storage S3-compatibile per il versioning storico, ma per il quotidiano \u00e8 lui che fa il lavoro.<\/p>\n<hr>\n<blockquote>\n<p>Immagine generata con ComfyUI Mac M1 \/ RealVisXL V5 Lightning.<\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>Sincronizzare file fra macchine diverse senza affidarsi a un cloud di terzi \u00e8 una di quelle abitudini che mi hanno cambiato il modo di lavorare. Sulla scrivania ho un portatile Linux, in salotto un Mac mini dedicato al multimedia, in un angolo un paio di Raspberry Pi e su un provider cloud un piccolo server [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":186,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-3","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-self-hosting"],"_links":{"self":[{"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/3","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3"}],"version-history":[{"count":10,"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/3\/revisions"}],"predecessor-version":[{"id":353,"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/3\/revisions\/353"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=\/wp\/v2\/media\/186"}],"wp:attachment":[{"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rpi.temporiti.net\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}