Come distribuire i container Docker su server remoti

  • L'utilizzo di Docker Compose e SSH o GitHub Actions semplifica la distribuzione dei container su server remoti e facilita l'aggiornamento dei servizi.
  • Strumenti come WSL 2, VS Code e Dev Containers consentono lo sviluppo in ambienti Docker remoti con un'esperienza quasi locale.
  • Plesk e Portainer offrono interfacce web per la gestione di host Docker locali e remoti, stack Compose, volumi e immagini.
  • Con VNC/noVNC e Caddy è possibile eseguire applicazioni grafiche in contenitori remoti e accedervi in ​​modo sicuro dal browser.

Distribuzione di contenitori Docker su server remoti

Lavorare con i container Docker su server remoti È diventato il pane quotidiano di chiunque voglia distribuire applicazioni moderne senza impantanarsi in dipendenze, versioni di librerie e il classico "funziona sulla mia macchina". Tuttavia, quando passiamo dall'esecuzione di un semplice docker run Passando dall'impostazione di una distribuzione seria in locale su un server Linux, con Docker Compose, condivisioni GitHub, Plesk, Portainer o persino applicazioni grafiche accessibili tramite browser, le cose si fanno un po' più complicate.

Se il tuo obiettivo è distribuire contenitori Docker su un server remoto (Ubuntu, Debian, Windows con WSL 2, un Cloud Server, Plesk, ecc.) e farlo in modo gestibile, automatizzato e sicuro, in questa guida troverai un percorso abbastanza completo: dall'uso base di Docker Compose da remoto, agli ambienti di sviluppo con VS Code, alle distribuzioni da Plesk, all'amministrazione con Portainer e all'esecuzione remota di applicazioni grafiche utilizzando noVNC e Caddy.

Concetti di base: contenitori Docker e distribuzione remota

Docker è una piattaforma di container Pacchettizza un'applicazione con tutto il necessario (librerie, dipendenze, binari, configurazione di sistema minima) in modo che possa essere eseguita su qualsiasi macchina con il motore Docker installato. La differenza principale rispetto a una macchina virtuale è che il contenitore non include un sistema operativo completo; condivide invece il kernel host, con conseguenti immagini più leggere e prestazioni migliori.

Per distribuire contenitori Docker su server remoti In genere, si dispone di un host (ad esempio, un server Ubuntu nel cloud) con Docker e, facoltativamente, Docker Compose, a cui si invia il codice o le immagini per l'esecuzione. È possibile farlo manualmente tramite SSH, automatizzarlo con GitHub Actions o integrarlo con pannelli come Plesk o strumenti come Portainer.

I principali scenari reali che incontrerai Quando si parla di "Docker remoto", ci sono tre aspetti: sviluppo locale ma esecuzione di container su un'altra macchina (o in WSL 2), distribuzione automatizzata di servizi backend/frontend e gestione dei container di produzione (monitoraggio, registrazione, riavvii, policy di rete, ecc.). La tecnologia è la stessa; ciò che cambia è il modo in cui viene orchestrata.

Oltre ai tradizionali servizi di backendDocker consente qualcosa di meno noto ma molto potente: eseguire applicazioni grafiche (client di posta elettronica, IDE, strumenti di analisi, ecc.) all'interno di container remoti e accedervi da un browser tramite VNC su WebSocket. È un modo pratico per sfruttare server potenti quando il PC non è abbastanza potente.

Da Docker Run a Docker Compose su un server remoto

Utilizzo di Docker Compose su un server remoto

Un modello abbastanza comune di distribuzione manuale Consiste nell'avere un repository di codice su GitHub, un server Ubuntu remoto con Docker installato e un flusso di lavoro CI/CD (ad esempio, GitHub Actions) che esegue le seguenti operazioni quando si esegue il push su un ramo come development o main:

  • Connettersi al server remoto tramite SSH.
  • Arrestare e rimuovere i contenitori in funzione.
  • Scarica le nuove immagini da Docker Hub (o dal tuo registro privato).
  • corsa docker run per ogni servizio.
  • Consenti a Nginx (o al proxy inverso che utilizzi) di reindirizzare il traffico alle porte di ciascun contenitore.

Quando si passa a Docker Compose Il flusso è notevolmente semplificato, perché invece di gestire i contenitori uno per uno, definisci l'intero stack (frontend, backend, database, cache, ecc.) in un unico docker-compose.yml, con le sue reti, volumi e variabili ambientali.

La pratica più semplice (e abbastanza comune) con GitHub Actions Il flusso di lavoro dovrebbe eseguire un cd alla directory del progetto sul server remoto (dove si trova il tuo docker-compose.yml) ed eseguire comandi come:

  • docker compose pull per portare le immagini più recenti.
  • docker compose down per fermare e rimuovere i vecchi contenitori (facoltativamente con --remove-orphans).
  • docker compose up -d --build se si creano immagini dal server stesso.

Questo approccio funziona bene ed è abbastanza robustoA patto di avere un buon controllo sulle credenziali, sulle variabili di ambiente e sui volumi, è possibile migliorare la sicurezza impedendo a GitHub Actions di avere accesso root completo al server, limitando le chiavi SSH, utilizzando utenti dedicati o persino esponendo Docker come servizio remoto sicuro con certificati, invece di eseguire tutto tramite SSH.

Non esiste un "metodo magico" migliore di questo. Per un ambiente semplice: la chiave è automatizzare e scrivere bene il docker-compose.ymlUtilizzare tag immagine immutabili (ad esempio, versioni specifiche) e avere un meccanismo di rollback (ad esempio, salvare la versione precedente della composizione o delle immagini).

Ambiente di sviluppo remoto con Docker, WSL 2 e VS Code

Docker remoto con VS Code e WSL 2

Su Windows è molto comune sviluppare con Docker utilizzando WSL 2.Docker Desktop per Windows offre un motore basato su WSL 2 che consente di eseguire container Linux e Windows dalla stessa macchina, modificando il codice con VS Code ed eseguendo test nel browser locale.

Il flusso di lavoro tipico per la configurazione di un ambiente di sviluppo con contenitori remoti utilizzando WSL 2 È il seguente:

  1. Installa WSL 2 e una distribuzione Linux (ad esempio Ubuntu).
  2. Installa Docker Desktop su Windows e abilita l'opzione "Usa motore basato su WSL 2" in Impostazioni > Generali.
  3. In Impostazioni > Risorse > Integrazione WSL, seleziona le distribuzioni WSL su cui desideri che Docker funzioni.
  4. Si controlla l'installazione con docker --version e correre docker run hello-world all'interno della distribuzione WSL.

Sviluppare “dentro” i contenitori E non usare solo Docker come motore: VS Code è fondamentale. Con le estensioni WSL, Dev Containers e Docker, puoi fare cose come:

  • Apri la cartella del progetto ospitata in WSL direttamente in VS Code.
  • Riaprire quella cartella "in un contenitore di sviluppo" (Dev Container), utilizzando un Dockerfile e devcontainer.json che descrivono il tuo ambiente ideale (versione Python, Node, ecc.).
  • Esegui il debug dell'applicazione da VS Code mentre è in esecuzione nel contenitore.

Un esempio molto comune Funziona con un progetto Django o Node.js: cloni il repository all'interno di WSL, apri la cartella con code .Selezionando una definizione di Dev Container (ad esempio, "Python 3"), VS Code crea l'immagine e avvia il container con tutte le dipendenze. Da lì, è possibile eseguire, eseguire il debug e verificare che il codice venga eseguito su Linux anche se il sistema host è Windows.

Questo approccio è utile anche quando la tua macchina non è molto potentePerché puoi spostare parte del carico su un server remoto con Docker e connetterti ad esso con VS Code tramite SSH e Dev Containers, lavorando quasi come se fosse locale ma affidandoti alle risorse del server.

Distribuzione di applicazioni su un server cloud con Docker e Docker Compose

Configura un server cloud con Docker pronto per la distribuzione Con la maggior parte dei provider è molto veloce: scegli un'immagine di sistema in cui Docker è già preinstallato, attendi qualche minuto e il tuo computer è pronto a ricevere i container.

Un modello tipico per la distribuzione di una semplice applicazione Node.js Sarebbe questo:

  1. Crea il progetto Node.js (ad esempio, un "Hello world" con Express) sul tuo computer locale: cartella del progetto, sottodirectory app, npm init, installazione di dipendenze (come express) e a index.js che imposta un server sulla porta 3030 con un messaggio di base.
  2. Dockerizza l'app con un Dockerfile che definisce l'immagine di base (ad esempio node:12), The WORKDIRCopia i file dell'app, esegui npm install ed esporre la porta interna.
  3. Aggiungere un .dockerignore per evitare di mettere cose come node_modules.
  4. Creazione di un finestra mobile-compose.yml nella radice del progetto, indicando la versione (ad esempio, 3.8) e definendo il servizio principale, il suo build, mappatura delle porte (3030:3030) e il comando (node index).

Una volta che hai il progetto e la composizione prontiLa distribuzione sul server remoto segue solitamente questo flusso:

  • Ci si connette al server tramite SSH.
  • Cloni il repository o carichi i file (Git, SCP, rsync…).
  • Tu installi finestra mobile-composizione se non fosse già presente (in molte distribuzioni è necessario installarlo separatamente da Docker, ad esempio scaricando il binario da GitHub e assegnandogli i permessi di esecuzione).
  • Esegui docker-compose up (o docker compose up (a seconda della versione) in modo che le immagini vengano scaricate, l'immagine dell'app venga creata e i contenitori vengano avviati.

Un punto che spesso viene trascurato è il firewall del fornitore.Se il tuo servizio è in ascolto sulla porta 3030, dovrai aprirlo nelle regole del firewall o creare una policy specifica e associarlo al server. In caso contrario, dall'esterno verrà visualizzato solo il messaggio "connessione rifiutata", anche se il container funziona correttamente.

Una volta operativo, potrai accedere all'applicazione utilizzando l'indirizzo IP pubblico del server e la porta esposta (ad esempio, https://IP_DEL_SERVIDOR:3030), oppure nascondendo quella porta dietro un proxy inverso come Nginx/Traefik che ascolta sulla porta 80/443.

Gestione di container remoti con Plesk e Docker

Se utilizzi Plesk come pannello di controlloÈ anche possibile utilizzare l'estensione Docker per gestire i container direttamente dall'interfaccia web, sia sul server stesso che sugli host Docker remoti.

Plesk supporta Docker su una buona varietà di sistemi operativiCentOS 7, RHEL 7, Debian 10/11/12, varie versioni di Ubuntu (18.04, 20.04, 22.04, 24.04), AlmaLinux 8/9, Rocky Linux 8.x e Virtuozzo 7 aggiornato. In Plesk per Windows, Docker non viene eseguito localmente ma su una macchina remota che funge da host Docker.

Ci sono alcune limitazioni importanti da tenere a mente:

  • Non è possibile utilizzare l'estensione Docker se Plesk è distribuito all'interno di un contenitore Docker.
  • Per utilizzare i servizi Docker remoti (ad esempio host esterni), è necessaria una licenza aggiuntiva o pacchetti specifici (Hosting Pack, Power Pack, Developer Pack).
  • I contenitori Docker gestiti da Plesk non sono "migrabili" in quanto tali, sebbene sia possibile eseguire il backup dei dati che utilizzano tramite volumi o snapshot.

Dall'interfaccia di Plesk puoi cercare le immagini sia nel repository locale (immagini già scaricate sull'host) sia in Docker Hub. Per avviare un container, il pannello ti guida:

  1. Ir un Docker > Contenitori > Esegui contenitore.
  2. Trova l'immagine desiderata e consulta la relativa documentazione su Docker Hub (se applicabile).
  3. Facoltativamente, seleziona un'etichetta/versione specifica dell'immagine.
  4. Configurare i parametri del contenitore (variabili di ambiente, porte, volumi, memoria, avvio automatico, ecc.) e fare clic su Esegui.

Plesk consente anche di gestire le impostazioni avanzate Per ogni contenitore: riassegnare le porte (automaticamente o manualmente), decidere se la porta è accessibile da Internet o solo da localhost, limitare la RAM che il contenitore può consumare, definire i volumi (percorso sull'host e nel contenitore) o aggiungere tutte le variabili di ambiente necessarie.

Per quanto riguarda l'aspetto dell'orchestrazione remotaPlesk può funzionare con "servizi Docker remoti". Ciò comporta la configurazione del demone Docker sull'host remoto (ad esempio, utilizzando un /etc/docker/daemon.json con supporto per socket TLS e TCP), genera certificati .pem e registrare quell'host in Plesk da Docker > Ambienti > Aggiungi serverQuindi puoi contrassegnare quel nodo Docker come attivo e passare da un server all'altro dalla stessa interfaccia.

Distribuisci stack Docker Compose da Plesk

Se utilizzi già Docker Compose per la tua infrastrutturaPotrebbe interessarti far sì che Plesk gestisca la distribuzione di "stack" dai file. docker-compose.yml.

Il flusso di lavoro per la distribuzione di Compose in Plesk È relativamente semplice:

  1. Entrare Docker > Stack > Aggiungi stack.
  2. Assegna un nome di progetto allo stack.
  3. Scegli la fonte del file Compose: editor (incolla il contenuto), carica un file dal tuo computer o seleziona un file esistente nello spazio web di un dominio.
  4. Confermare la configurazione e consentire a Plesk di dichiarare e creare i contenitori definiti.

Tutto ciò che viene costruito durante il processo di costruzione Il Compose associato viene archiviato nella directory principale del sito Web, il che facilita l'accesso ai log, agli artefatti intermedi o ai file aggiuntivi generati dalla build.

Plesk facilita anche la gestione delle immagini locali: da Docker > Immagini È possibile filtrare, rivedere i tag dei diversi prodotti, visualizzare lo spazio utilizzato ed eliminare le immagini obsolete per liberare spazio su disco. Questa funzionalità è importante in ambienti remoti con spazio limitato.

Se utilizzi Nginx come server web front-endPlesk applica regole proxy (ad esempio, in nginx.conf (dal dominio) per instradare il traffico verso i container Docker, anche in scenari con NAT. Questo ti evita di dover gestire manualmente le configurazioni del reverse proxy su server remoti.

Gestisci i contenitori remoti con Portainer

Portainer è un'interfaccia web leggera Per Docker, semplifica notevolmente il lavoro quotidiano di chi non vuole lavorare sulla riga di comando. Funziona come un contenitore e può gestire l'host locale o più host remoti (anche con Portainer Agent).

Per installare Portainer sul tuo server utilizzando Docker Di solito si seguono questi semplici passaggi:

  • Creare un volume per i dati Portainer: docker volume create portainer_data.
  • Avviare il contenitore Portainer mappando le porte 8000 e 9000, montando il socket Docker (/var/run/docker.sock) e il volume dei dati: docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer.

In questo modo Portainer sarà in ascolto sulla porta 9000 del server.Come sempre, dovrai aprire la porta nel tuo firewall o esporla tramite un proxy inverso HTTPS. La prima volta che accedi tramite browser, Portainer ti chiederà di creare un utente amministratore, dopodiché potrai scegliere se gestire il Docker locale o altri host remoti.

Il pannello Portainer è piuttosto intuitivo.Potrai visualizzare i container attivi, i relativi log, le statistiche sul consumo di risorse, gli stack Compose, le reti, i volumi e altro ancora. E, soprattutto, ti consente di ricreare i container con parametri diversi, aggiornare le immagini, gestire gli stack e centralizzare più server remoti da un'unica interfaccia.

Eseguire applicazioni grafiche in contenitori remoti e accedervi tramite un browser

Quando il tuo computer esaurisce le risorse Ma se hai bisogno di utilizzare applicazioni grafiche pesanti (come client di posta elettronica, IDE o strumenti di reverse engineering), una soluzione molto interessante è quella di eseguirle in contenitori Docker su un server potente e accedervi tramite il Web.

Uno studio di caso molto ben documentato L'idea è di incapsulare Mozilla Thunderbird in un contenitore, esporre la sua interfaccia grafica tramite TigerVNC/noVNC e proteggere l'accesso con Caddy. Questo concetto può essere riutilizzato per quasi tutte le applicazioni GUI Linux.

L'architettura di base di questo tipo di contenitore grafico di solito include:

  • Un server VNC/X11 leggero (TigerVNC) che funge da server di visualizzazione.
  • Un gestore di finestre minimalista (OpenBox) per la gestione delle finestre.
  • Un tipo di server piccolo e facile da usare easy-novnc che espone VNC come WebSocket e genera una pagina HTML per connettersi dal browser.
  • supervisord o simile per avviare e monitorare tutti i processi all'interno del contenitore.
  • L'applicazione stessa (Thunderbird, GIMP, ecc.) configurata per essere visualizzata sul display remoto (DISPLAY=:0).

In pratica viene creata una directory di lavoro. (per esempio, ~/thunderbird) dove sono posizionati:

  • Un conf.supervisore che definisce i programmi da avviare: TigerVNC, easy-novnc, OpenBox e l'applicazione principale, con priorità in modo che il server grafico venga avviato prima dell'app.
  • Un menu.xml OpenBox configura il menu del desktop (applicazione principale, terminale, monitor di processo con htop, ecc.).
  • Un Dockerfile multistadio che nella prima fase compila easy-novnc con Go, e nel secondo passaggio crea l'immagine finale su Debian, installando openbox, tigervnc, supervisor, le utility della console, l'applicazione (Thunderbird nell'esempio), copiando i binari e le configurazioni, creando un utente non root e definendo un volume di dati persistente in /data.

Il comando predefinito del contenitore è solitamente delegato a supervisord, avviandolo come un normale utente utilizzando gosuDopo aver regolato le autorizzazioni sul volume di dati, all'avvio del contenitore vengono avviati automaticamente VNC, noVNC, il gestore delle finestre e l'applicazione, e sarà necessario accedere solo alla porta HTTP esposta da easy-novnc.

Per renderlo più robusto e facile da usare per InternetÈ una buona idea posizionare un server web come Caddy all'inizio, sempre in un contenitore, che funga da proxy inverso per la tua app grafica, aggiunga l'autenticazione di base (nome utente e password con hash) e, facoltativamente, esponga un WebDAV per accedere ai file. /data dal tuo computer locale.

Orchestrare la soluzione con reti, volumi e Caddy

Per mantenere organizzato questo tipo di distribuzione L'approccio più comune è quello di creare la propria rete Docker e uno o più volumi di dati:

  • Rete, per esempio thunderbird-net, che sarà condiviso da tutti i contenitori correlati.
  • Volume thunderbird-data che conterrà il profilo utente e i dati persistenti dell'app grafica.

Il contenitore dell'applicazione grafica Puoi avviarlo con qualcosa del tipo:

  • Politica --restart=always in modo che possa stare in piedi da solo.
  • Assemblaggio del volume thunderbird-data:/data.
  • Conexion a la red thunderbird-net.
  • Nome identificabile (thunderbird-app(ad esempio) che Caddy utilizzerà per il proxy inverso.

In un'altra directory (ad esempio, ~/caddy) l'immagine di Caddy è costruita con i moduli necessari (come il plugin WebDAV) e un Caddyfile che definisce:

  • Un server sulla porta 8080.
  • Un reverse_proxy a thunderbird-app:8080 (o la porta esposta da noVNC).
  • Percorsi aggiuntivi per la navigazione tra i file (/files) e per WebDAV (/webdav), entrambi al servizio del contenuto del volume di dati.
  • Un blocco di basicauth che protegge tutti i percorsi con un utente e una password hash letti dalle variabili di ambiente.

Durante la creazione del contenitore Caddylo stesso volume è assemblato thunderbird-data:/data, si connette alla rete thunderbird-net e la sua porta è pubblicata (ad esempio, -p 8080:8080) sull'host. Con questo, devi solo andare nel tuo browser per http://IP_DEL_SERVIDOR:8080Inserisci le tue credenziali e clicca su Connetti per iniziare a utilizzare l'applicazione grafica da remoto.

La manutenzione a lungo termine è sempliceQuando è necessario effettuare un aggiornamento, è possibile arrestare ed eliminare i contenitori, ricostruire le immagini con le nuove versioni e riavviarle. docker run mantenendo il volume dei dati, in modo che le impostazioni e i file dell'utente rimangano intatti.

Con tutti questi pezzi (Docker Compose, Plesk, Portainer, VS Code, WSL 2, Caddy, noVNC…) È possibile configurare di tutto, da semplici distribuzioni backend a desktop remoti incapsulati in container e perfettamente accessibili tramite browser, sfruttando server con una potenza molto maggiore rispetto alla propria macchina e mantenendo un controllo piuttosto preciso su reti, sicurezza, storage e aggiornamenti.