SSD Nodes Learn Hosting plans →
Guide Matt ConnorDi Matt Connor

Dokploy dietro NetBird: dashboard e app private

Rendi la dashboard di Dokploy e le tue app raggiungibili solo dai peer NetBird: client fissato, firewall del provider, proxy privato e webhook GitHub.

Dokploy dietro NetBird: la risposta breve

Per mettere Dokploy dietro NetBird installi il client NetBird sull'host Dokploy, apri la dashboard sull'IP NetBird dell'host e poi chiudi le porte pubbliche nel firewall del provider. Da quel momento la dashboard sulla porta 3000 e le tue app rispondono solo ai peer della tua rete NetBird. Il proxy NetBird-Only, arrivato con la v0.72, è un livello in più. Ti dà nomi HTTPS privati senza pagina di login, ma richiede un proxy configurato apposta.

Questa guida è il passo successivo a installare un server NetBird self-hosted sul tuo VPS. In quella guida hai risposto no alla domanda sul NetBird Proxy. Qui vediamo prima la parte che resta valida tra una versione e l'altra. Poi passiamo al proxy, che è opzionale.

Perché in questa guida servono due VPS e non uno

Dokploy e il quickstart di NetBird vogliono entrambi le porte 80 e 443. L'installer di Dokploy usa la 80 e la 443 per il suo Traefik e la 3000 per la dashboard. Se una di queste porte è già occupata, l'installazione si ferma. Il quickstart di NetBird chiede che la macchina sia raggiungibile da internet su TCP 80 e 443 e su UDP 3478. Nella configurazione predefinita usa anche lui Traefik, che gestisce i certificati Let's Encrypt. Due processi non possono ascoltare sulla stessa porta della stessa macchina.

Spostare uno dei due su altre porte sembra la soluzione più semplice. Il problema è che il proxy di NetBird ha bisogno del TLS passthrough, cioè deve ricevere la connessione cifrata senza aprirla. La guida di migrazione di NetBird dice che tra i reverse proxy comuni "only Traefik supports it". Nginx, Caddy e Nginx Proxy Manager invece terminano il TLS da soli. Sul forum di NetBird, nel thread 811, un utente aveva un secondo cluster proxy accanto al Traefik integrato e ha trovato subito il conflitto sulle porte 80 e 443. Ha spostato il suo proxy su 280 e 2443, e un altro utente gli ha consigliato una VM separata. La documentazione ufficiale però descrive anche l'installazione del server NetBird su un Traefik già attivo sullo stesso host. Con l'opzione 1 dello script di installazione, NetBird genera solo le etichette Traefik per i container della dashboard e di netbird-server, e la pagina lo dice chiaramente: "It does not run Traefik for you". Routing, TLS e certificati restano al Traefik esistente. Due VPS quindi non sono un obbligo in generale, ma io non ho verificato questa configurazione con il Traefik di Dokploy.

In questa guida però il secondo VPS serve. Tra i requisiti dell'opzione 1 ci sono le porte 80 e 443 dell'host raggiungibili da internet, e il quickstart chiede anche UDP 3478. Più avanti chiudi proprio la 80 e la 443 sull'host Dokploy, quindi il server NetBird deve stare su un'altra macchina. Inoltre la pagina dell'opzione 1 non dice se il proxy di NetBird, quello che serve per i nomi NetBird-Only, funziona in quella configurazione.

Lo schema consigliato quindi è questo:

  • VPS 1, piccolo: il server NetBird, con management, signal, relay e il suo Traefik. Resta pubblico, perché i peer devono raggiungerlo.
  • VPS 2: Dokploy, con il client NetBird installato. Questo diventa privato.
  • Al posto del VPS 1 puoi usare NetBird Cloud. Più avanti vedi cosa cambia per il proxy privato.

Dokploy raccomanda almeno 2 GB di RAM e 30 GB di disco per il VPS 2. Il quickstart di NetBird chiede per il VPS 1 "at least 1CPU and 2GB of memory", quindi nemmeno quello può essere minuscolo. Se stai ancora scegliendo la piattaforma di deploy, il confronto tra Coolify e Dokploy spiega cosa cambia tra le due.

Installare il client NetBird sull'host Dokploy con una versione fissata

Lo script ufficiale curl -fsSL https://pkgs.netbird.io/install.sh | sh installa sempre l'ultima versione. La documentazione Linux di NetBird non descrive un modo per fissare la versione con lo script o con i pacchetti apt. L'unico metodo documentato per scegliere la versione è il tarball binario: sostituisci la versione nell'URL di download.

Fissare la versione conta, perché NetBird rilascia spesso. Il 24 ottobre è uscita la v0.81.4, con correzioni sui privilegi SSH e la revoca della fiducia nelle chiavi compromesse della CA eMudhra. Al 27 ottobre 2026 la release marcata Latest su GitHub è la v0.81.5, uscita il 26 ottobre con due correzioni SSH lato client. In cima alla pagina compare anche la v0.82.0-rc.1, pubblicata lo stesso giorno: è una pre-release, quindi non usarla qui. Questa guida usa la v0.81.5. Prima di copiare i comandi apri la pagina delle release di NetBird e cambia NB_VERSION se è uscita una versione più nuova marcata Latest.

Controlla prima l'architettura del VPS. uname -m stampa x86_64 su un VPS Intel o AMD, e in quel caso usi amd64. Se stampa aarch64, usi arm64.

uname -m
NB_VERSION=0.81.5
ARCH=amd64
curl -L -o ./netbird_${NB_VERSION}.tar.gz \
  https://github.com/netbirdio/netbird/releases/download/v${NB_VERSION}/netbird_${NB_VERSION}_linux_${ARCH}.tar.gz
tar xzf ./netbird_${NB_VERSION}.tar.gz
sudo mv netbird /usr/bin/netbird
sudo chown root:root /usr/bin/netbird
sudo chmod +x /usr/bin/netbird
sudo netbird service install
sudo netbird service start

Se sudo netbird service install stampa un errore che contiene Exec format error, hai scaricato l'architettura sbagliata. Rifai il download con il valore giusto di ARCH.

Ora crea una setup key nella dashboard di NetBird e collega l'host. Con un server self-hosted passi anche l'URL del management, cioè lo stesso indirizzo HTTPS che apri nel browser per la dashboard di NetBird. Con NetBird Cloud togli --management-url.

netbird up --setup-key <SETUP_KEY> --management-url https://netbird.example.com
netbird status
ip addr show wt0

netbird status deve indicare che il client è connesso al management e al signal. ip addr show wt0 mostra l'interfaccia del tunnel con l'indirizzo NetBird dell'host. Annota questo indirizzo: da qui in avanti lo chiamiamo IP_NETBIRD. wt0 è il nome predefinito dell'interfaccia, e cambia se hai passato --interface-name a netbird up. Se ip addr show wt0 dice che il dispositivo non esiste, leggi l'indirizzo nella riga NetBird IP di netbird status. Se invece netbird status non mostra il client connesso, rileggi l'output di netbird up e controlla la setup key e l'URL.

Aprire la dashboard di Dokploy sull'IP NetBird

Dokploy pubblica la dashboard come porta Docker 3000. Una porta pubblicata da Docker senza un indirizzo specifico ascolta su tutte le interfacce dell'host, quindi anche su wt0. Puoi controllarlo sull'host:

sudo ss -tlnp | grep ':3000'

Una riga con 0.0.0.0:3000 oppure *:3000 significa che la porta risponde su ogni interfaccia. Poi esegui questo da un portatile collegato alla stessa rete NetBird:

curl -sI http://IP_NETBIRD:3000

Qualsiasi risposta HTTP, anche un redirect, dimostra che il percorso funziona. A quel punto apri http://IP_NETBIRD:3000 nel browser. La connessione usa HTTP semplice, ma viaggia dentro il tunnel WireGuard di NetBird, quindi è cifrata tra il portatile e il VPS. Se curl resta fermo e poi esce con l'errore 28 (timeout), di solito manca una policy. Nella dashboard di NetBird il gruppo del tuo portatile deve poter raggiungere il peer Dokploy.

Esporre dokploy-network come risorsa NetBird

Le app che Dokploy pubblica girano in container collegati alla rete Docker dokploy-network. La guida Tailscale di Dokploy trova la subnet di questa rete con docker network inspect, e con NetBird usi lo stesso comando:

docker network inspect dokploy-network | grep -E 'Driver|Subnet'

Nella guida di Dokploy l'output di esempio è "Subnet": "10.254.0.0/24". Il tuo valore può essere diverso, quindi usa quello che vedi. Poi, nella dashboard di NetBird:

  1. In Networks crea una rete, per esempio dokploy.
  2. Aggiungi una risorsa con la subnet letta sopra e assegnala a un gruppo di risorse, per esempio dokploy-apps.
  3. Assegna l'host Dokploy come routing peer di questa rete. Il routing peer è il client NetBird che sta dentro la rete privata e inoltra il traffico verso di essa.
  4. Crea una policy di accesso dal gruppo dei tuoi dispositivi verso dokploy-apps. La documentazione di NetBird è chiara: senza una policy la risorsa non è raggiungibile.

Qui c'è un compromesso da capire. La documentazione di NetBird consiglia risorse /32, cioè un solo host, invece di intervalli larghi. Così una policy apre un host e non una subnet intera. Con Docker però un /32 regge poco, perché un container ricreato a ogni deploy può ricevere un IP diverso. La subnet intera è stabile, ma apre ogni container collegato a dokploy-network. Limita almeno la policy ai protocolli e alle porte delle tue app, invece di permettere tutto.

La documentazione di NetBird non dice se un routing peer raggiunge gli IP dei container sul suo stesso host. Il campo Driver dell'output sopra ti dice che tipo di rete Docker è. Prova quindi prima dall'host stesso:

docker network inspect dokploy-network | grep -E '"Name"|IPv4Address'
curl -sI http://IP_CONTAINER:PORTA

Se l'host non raggiunge l'IP del container, nemmeno i peer lo raggiungeranno, perché il routing peer inoltra il traffico partendo dall'host. In quel caso rinuncia alla risorsa e usa la dashboard sull'IP NetBird, oppure il proxy NetBird-Only descritto più avanti. Se l'host risponde, ripeti lo stesso curl dal portatile.

Prima di chiudere le porte: verificare SSH su NetBird

Se chiudi la porta 22 mentre l'unico accesso è l'IP pubblico, perdi l'accesso al tuo server. Prima controlla che sshd ascolti su tutte le interfacce:

sudo ss -tlnp | grep ':22 '

Vuoi vedere 0.0.0.0:22 e [::]:22. Una riga con solo l'IP pubblico significa che sshd ascolta solo su quell'indirizzo, e allora SSH non risponderà su wt0. Spesso la causa è una direttiva ListenAddress in /etc/ssh/sshd_config, ma l'indirizzo da solo non dice da dove arriva. Il manuale di OpenSSH ricorda che le opzioni sulla riga di comando prevalgono sul file di configurazione: -o può impostare ListenAddress all'avvio, e -f può far leggere a sshd un altro file. Poi, senza chiudere la sessione SSH attuale, apri un secondo terminale sul portatile:

ssh utente@IP_NETBIRD

Se entri, l'accesso di emergenza è pronto. Se la connessione va in timeout, controlla due cose. La prima è la policy di NetBird, che deve permettere TCP 22 verso l'host Dokploy. La seconda è il firewall dell'host: la documentazione di NetBird avverte che "UFW may evaluate its deny rules before NetBird's allow rules", e in quel caso i peer risultano connessi in netbird status ma il traffico non passa. Con UFW la correzione documentata è sudo ufw allow in on wt0, che non apre porte verso internet. Risolvi prima di andare avanti.

Chiudere 22, 80, 443 e 3000 nel firewall del provider

Il firewall giusto è quello del provider, non UFW. La documentazione di Docker lo dice in modo diretto: il traffico verso una porta pubblicata da un container "gets diverted before it goes through the ufw firewall settings". Docker inserisce le sue regole prima di quelle di UFW, quindi ufw deny 3000 non blocca la dashboard di Dokploy. La spiegazione completa è in perché le porte Docker scavalcano UFW.

Il firewall di rete del provider filtra i pacchetti prima che arrivino al VPS, quindi le regole di Docker non contano. I passaggi cambiano da provider a provider. Nel pannello crea regole che blocchino in ingresso TCP 22, 80, 443 e 3000 da internet, e applica il firewall al VPS 2. Non bloccare il traffico in uscita. Molti firewall dei provider scartano tutto ciò che non è permesso esplicitamente appena li attivi. Dopo l'attivazione controlla subito il tunnel:

netbird status

Il client deve risultare ancora connesso, e la sessione ssh utente@IP_NETBIRD deve funzionare. Poi verifica da una macchina che non è nella rete NetBird, per esempio un altro server:

nc -zv -w 5 IP_PUBBLICO 3000
nc -zv -w 5 IP_PUBBLICO 22

Entrambi i comandi devono andare in timeout. Se uno risponde succeeded, la regola non è attiva o non è applicata a questo VPS. Per altri modi di provare una porta vedi come controllare se una porta è aperta su Linux.

Cosa succede ai certificati Let's Encrypt di Dokploy

Let's Encrypt verifica un dominio contattando il tuo server da internet. La sfida HTTP-01 usa la porta 80 e la sfida TLS-ALPN-01 usa la 443. Con entrambe chiuse, il Traefik di Dokploy non può ottenere nuovi certificati con queste sfide. I certificati già emessi restano validi fino alla scadenza, poi il rinnovo fallisce.

Hai tre strade. La prima è usare HTTP semplice dentro il tunnel, come per la dashboard, perché WireGuard cifra già il traffico. La seconda è il proxy NetBird-Only, che gestisce l'HTTPS sul VPS 1. La terza vale per le app che devono restare pubbliche: un Cloudflare Tunnel senza porte aperte le serve senza riaprire la 80 e la 443.

Il livello opzionale: i servizi NetBird-Only

NetBird ha aggiunto i servizi privati del reverse proxy con la v0.72, annunciata a giugno 2026. Un servizio con accesso NetBird-Only non viene più servito in pubblico. Il proxy lo serve su un listener legato al suo tunnel WireGuard. Non c'è pagina di login e non ci sono credenziali: l'identità del peer che si collega è la credenziale. Il proxy riconosce il peer da cui arriva la richiesta. Se il peer appartiene a un utente, il management confronta i gruppi di quell'utente con i gruppi di accesso del servizio, e i gruppi del peer non contano. Solo per i peer senza utente, come i proxy di un cluster, conta l'appartenenza del peer stesso. Una richiesta il cui utente non è in nessuno di quei gruppi riceve un 403. Il nome del servizio si risolve da solo dentro la rete NetBird, perché NetBird crea i record DNS e le policy a partire dalla configurazione del servizio.

Due limiti contano. Funziona solo con servizi HTTP: per i servizi L4 restano le normali restrizioni di accesso. Inoltre richiede un cluster proxy con la capacità Private. Un cluster senza questa capacità mostra l'opzione NetBird-Only in grigio nella dashboard.

Attivare la capacità Private sul server self-hosted

Nella guida precedente hai rifiutato il proxy, quindi devi prima aggiungerlo seguendo la guida di NetBird per abilitare il reverse proxy. Ti servono un dominio dedicato al proxy, per esempio proxy.example.com, e un record wildcard. Il record A (o AAAA) di proxy.example.com punta all'IP pubblico del VPS 1, e un CNAME *.proxy.example.com punta a proxy.example.com. Il record base serve perché un wildcard non copre il dominio nudo.

Il quickstart non genera il flag Private, quindi lo aggiungi tu. La documentazione Bring Your Own Proxy di NetBird dice che un proxy in modalità embedded riporta la capacità se parte con --private o con la variabile NB_PROXY_PRIVATE=true. La tabella delle variabili nella guida di migrazione descrive la stessa variabile, con valore predefinito false, e la indica come necessaria per l'accesso NetBird-Only. Aggiungi questa riga al file proxy.env, che sta accanto a docker-compose.yml sul VPS 1:

NB_PROXY_PRIVATE=true

Poi ricrea il container del proxy dalla stessa cartella:

docker compose up -d proxy

Nella dashboard di NetBird l'opzione NetBird-Only non deve più essere in grigio. Crea un servizio con un nome sotto il dominio del proxy, per esempio dokploy.proxy.example.com. Come destinazione scegli il peer Dokploy e la porta 3000, poi imposta l'accesso NetBird-Only e i gruppi ammessi. Dal portatile:

curl -sI https://dokploy.proxy.example.com

Se il portatile appartiene a un utente che sta in uno dei gruppi ammessi, ricevi la risposta di Dokploy. Se l'utente non è in nessuno di quei gruppi ricevi un 403, anche quando il portatile stesso è in uno di essi. A un dispositivo fuori dalla rete NetBird il servizio non viene servito, anche se il wildcard DNS pubblico punta al VPS 1. Ripeti la stessa procedura per ogni app, con un servizio per app. Ricorda cosa resta pubblico: il VPS 1 continua ad ascoltare sulla 443, perché il proxy stesso è raggiungibile da internet. Privati sono solo i nomi che servi in modalità NetBird-Only.

Con NetBird Cloud: serve un proxy tuo (BYOP)

Al 27 ottobre 2026 la documentazione dice che i cluster condivisi di NetBird Cloud non riportano la capacità Private. Su Cloud la strada supportata è Bring Your Own Proxy (BYOP), cioè un proxy che fai girare tu sulla tua infrastruttura. BYOP è in beta. Usa le variabili NB_PROXY_DOMAIN e NB_PROXY_TOKEN, e la documentazione chiede di lasciare NB_PROXY_ADDRESS=:443. La porta 443 deve essere raggiungibile da internet per la sfida predefinita tls-alpn-01. La 80 serve solo se passi a http-01. Per creare i token del proxy serve il ruolo Network Admin o superiore, con il permesso Services.

Con la sfida predefinita quel proxy vuole la 443 raggiungibile da internet, e sull'host Dokploy la 443 è già del suo Traefik. NetBird però documenta anche un proxy BYOP privato senza porte web in ingresso. Il certificato arriva con la sfida DNS-01, tramite un client ACME esterno come lego, e il proxy parte con NB_PROXY_ACME_CERTIFICATES=false, NB_PROXY_CERTIFICATE_DIRECTORY e NB_PROXY_PRIVATE=true. In quella configurazione un VPS separato per il proxy non è un requisito documentato.

Sui costi, la pagina prezzi di NetBird Cloud al 27 ottobre 2026 riporta questi piani. Free costa 0 € con fino a 5 utenti e 100 macchine. Team costa 6 € per utente al mese e Business 12 € per utente al mese. Enterprise ha un prezzo su richiesta. Team e Business includono 100 macchine più 10 per utente, e ogni macchina in più costa 0,50 € al mese. NetBird fattura solo utenti e macchine attivi, cioè quelli che si sono connessi o hanno fatto login almeno una volta nel periodo di fatturazione. La pagina prezzi non elenca le funzioni del reverse proxy per piano, e la documentazione BYOP non nomina un piano. Prima di contare sul piano Free per BYOP, chiedi conferma a NetBird. Se stai ancora decidendo quale servizio usare, il confronto tra NetBird e Tailscale mette a confronto i due modelli.

I webhook di GitHub arrivano ancora a un Dokploy privato?

Questa è una domanda aperta, e va verificata sul tuo server. La documentazione di Dokploy descrive due strade per il deploy automatico. La prima è l'autodeploy con GitHub "without any configuration". La seconda è un webhook: attivi Auto Deploy nelle impostazioni dell'applicazione, copi l'URL del webhook e lo aggiungi nelle impostazioni webhook del repository GitHub. La documentazione non dice se Dokploy deve essere raggiungibile da internet.

Per il webhook il ragionamento è semplice. Un webhook è una richiesta HTTP che parte dai server di GitHub, e i server di GitHub non sono peer della tua rete NetBird. Un nome NetBird-Only quindi non può riceverla. Per la strada con l'app GitHub non ho verificato come arriva la notifica. Fai la prova con un push su un ramo di test, poi controlla in Dokploy se parte un deploy. Nel repository, sotto Settings e poi Webhooks, la scheda Recent Deliveries mostra ogni consegna con il suo codice di risposta.

Se la consegna fallisce, NetBird v0.81.0 offre un'alternativa. Ogni target di un servizio del reverse proxy ha un'azione di accesso, a scelta tra "Use service authentication" (il valore predefinito), "Bypass authentication" e "Block access". Crei un servizio pubblico per Dokploy protetto da SSO, e aggiungi un target solo per il percorso del webhook con "Bypass authentication". Quel percorso salta SSO, password, PIN e autenticazione via header. Le restrizioni CIDR, per paese e CrowdSec invece restano attive. GitHub pubblica gli intervalli IP dei suoi webhook in https://api.github.com/meta, sotto la chiave hooks, quindi puoi limitare quel percorso a quegli indirizzi. Nelle impostazioni di GitHub l'URL del webhook deve usare il nome del servizio pubblico, non l'indirizzo privato di Dokploy.

Quattro dettagli contano:

  • "Bypass authentication" non è disponibile sui servizi NetBird-Only. Il servizio per il webhook deve essere pubblico con SSO.
  • Aggiorna ogni proxy del cluster alla v0.81.0 o successiva prima di usare queste azioni. Un proxy più vecchio le ignora e continua ad applicare l'autenticazione del servizio.
  • Il percorso si confronta con il prefisso letterale più lungo, e le maiuscole contano. Copia il prefisso esatto dall'URL del webhook di Dokploy.
  • Quando un target usa un'azione, il proxy rifiuta con un 400 i percorsi ambigui: quelli con un segmento .. intero, con // o con separatori codificati. I punti dentro un nome, come in /.well-known/file..json, invece passano.

Questa soluzione ha un costo preciso: quel percorso torna raggiungibile da internet, filtrato solo dai limiti CIDR. Il resto di Dokploy resta dietro SSO.

FAQ

Perché UFW non basta per chiudere la porta 3000 di Dokploy?

La porta 3000 di Dokploy è una porta pubblicata da Docker. La documentazione di Docker spiega che il traffico verso una porta pubblicata da un container viene deviato prima di passare dalle regole di UFW, quindi ufw deny 3000 non ha effetto. Chiudi la porta nel firewall di rete del provider, che filtra i pacchetti prima che arrivino al VPS. Poi controlla con nc -zv -w 5 IP_PUBBLICO 3000 da una macchina fuori dalla rete NetBird.

Posso installare il server NetBird sullo stesso VPS di Dokploy?

Sì, ma non se vuoi rendere privato l'host Dokploy. NetBird documenta l'installazione del server su un Traefik già attivo sullo stesso host, che gestisce routing e certificati: lo script genera solo le etichette per i container di NetBird. Quella configurazione però richiede le porte 80 e 443 raggiungibili da internet, mentre questa guida le chiude, e la documentazione non dice se il proxy di NetBird funziona in quel modo. Io non l'ho provata con il Traefik di Dokploy. Per seguire questa guida metti il server NetBird su un piccolo VPS separato, oppure usa NetBird Cloud.

NetBird Cloud supporta i servizi NetBird-Only?

Al 27 ottobre 2026 la documentazione di NetBird dice che i cluster proxy condivisi di NetBird Cloud non riportano la capacità Private, che i servizi NetBird-Only richiedono. Su Cloud devi usare Bring Your Own Proxy, in beta, con un proxy tuo avviato con NB_PROXY_PRIVATE=true o --private. Con la sfida predefinita tls-alpn-01 quel proxy deve avere la 443 raggiungibile da internet. Con la sfida DNS-01 e un client ACME esterno, invece, la documentazione di NetBird descrive un proxy BYOP privato senza porte web pubbliche in ingresso.

Il deploy automatico da GitHub funziona se Dokploy è raggiungibile solo da NetBird?

Va verificato, perché la documentazione di Dokploy non lo dice. Un webhook parte dai server di GitHub, che non sono peer NetBird, quindi non può arrivare a un nome NetBird-Only. Fai un push di prova e guarda Recent Deliveries nelle impostazioni webhook del repository. Se la consegna fallisce, usa un servizio pubblico con SSO e imposta "Bypass authentication" solo sul percorso del webhook. Questa azione esiste da NetBird v0.81.0 e non è disponibile sui servizi NetBird-Only.

Questo articolo ti è stato utile?