Scopri come esporre e pubblicare correttamente le porte in Docker per abilitare la comunicazione tra i tuoi container e il mondo esterno. Questa guida copre tutto, dalla configurazione del Dockerfile e dei flag a runtime fino all'orchestrazione con Docker Compose e alle tecniche di troubleshooting.
Quando lavori con i container Docker, uno degli aspetti più importanti che ho incontrato è abilitare la comunicazione di rete tra i container e il mondo esterno. Senza una corretta configurazione delle porte, le applicazioni containerizzate restano isolate e inaccessibili. In questo articolo ti guiderò nel processo di esposizione delle porte Docker, una competenza fondamentale per chiunque lavori con applicazioni containerizzate.
Questa guida è pensata in particolare per sviluppatori software, ingegneri DevOps e professionisti IT che devono rendere le proprie applicazioni containerizzate accessibili a utenti, ad altri servizi o a sistemi esterni. Che tu stia distribuendo un server web, una API o un database all'interno di un container, capire come esporre le porte è essenziale per costruire sistemi funzionali basati su Docker.
Al termine di questo articolo, avrai una chiara comprensione di come funziona il networking in Docker, dei diversi metodi per esporre le porte e delle tecniche pratiche per applicare questi concetti nei tuoi progetti.
Prima di entrare nei dettagli tecnici, è importante capire cosa significa esposizione delle porte nell'ecosistema Docker.
Principi di isolamento della rete dei container
I container Docker sono progettati con l'isolamento come principio fondamentale. Questo isolamento è ottenuto tramite funzionalità del kernel Linux come i namespaces e i cgroups. I namespaces forniscono isolamento dei processi, garantendo che i processi all'interno di un container non possano vedere o interagire con processi di altri container o del sistema host. I cgroups, invece, gestiscono l'allocazione delle risorse, limitando quanto CPU, memoria e altre risorse un container può consumare.
Dal punto di vista della rete, ogni container riceve il proprio namespace di rete, completo di un'interfaccia Ethernet virtuale (coppia veth). Questa interfaccia si collega di default a una rete bridge di Docker, permettendo la comunicazione tra container pur mantenendo l'isolamento dalla rete dell'host. È come se ogni container avesse il proprio indirizzo di rete privato, invisibile al mondo esterno.
Nella configurazione predefinita, un container Docker è completamente isolato. I servizi in esecuzione al suo interno possono comunicare tra loro, ma sono irraggiungibili dall'esterno del container, persino dalla macchina host. Ed è qui che l'esposizione delle porte diventa necessaria.
Expose vs publish: distinzione semantica
Quando configuri le porte in Docker, incontrerai due concetti correlati ma distinti: esporre e pubblicare le porte.
Esporre le porte è principalmente una funzionalità di documentazione. Quando esponi una porta in Docker, stai essenzialmente aggiungendo metadati all'immagine del container, indicando che l'applicazione containerizzata ascolta su porte specifiche.
Tuttavia, esporre una porta non la rende effettivamente accessibile dall'esterno del container. Serve da documentazione per gli utenti della tua immagine.
Pubblicare le porte è ciò che rende davvero i servizi containerizzati disponibili al mondo esterno. La pubblicazione crea una mappatura tra una porta sulla macchina host e una porta all'interno del container. Quando pubblichi una porta, Docker configura la rete dell'host per inoltrare il traffico dalla porta host specificata alla corrispondente porta del container.
Ecco quando usare ciascun approccio:
Usa expose quando crei immagini destinate ad altri utenti Docker, per documentare quali porte usa la tua applicazione.
Usa publish quando hai bisogno che sistemi esterni (incluso l'host) accedano ai servizi in esecuzione nel tuo container.
Usali entrambi insieme per una documentazione completa e funzionalità effettiva, soprattutto in ambienti di produzione.
Come esporre le porte Docker
Ora che abbiamo capito i concetti, vediamo gli aspetti pratici dell'esposizione delle porte Docker in diversi contesti.
Strategie di dichiarazione nel Dockerfile
Il modo più basilare per esporre una porta è usare l'istruzione EXPOSE nel tuo Dockerfile. Questa dichiara le porte che il container è progettato per utilizzare.
In questo esempio, ho specificato che il container utilizzerà le porte 80 e 443, che sono standard per il traffico HTTP (Hypertext Transfer Protocol) e HTTPS (Hypertext Transfer Protocol Secure). Puoi anche combinarle in un'unica istruzione:
Quando specifichi le porte, è buona pratica includere il protocollo, TCP (Transmission Control Protocol) o UDP (User Datagram Protocol) se la tua applicazione ne usa uno specifico:
Se non viene specificato alcun protocollo, per impostazione predefinita si assume TCP. Questo è appropriato per la maggior parte delle applicazioni web, ma servizi come il DNS (Domain Name System) o i server di gaming spesso richiedono UDP.
Dal punto di vista della sicurezza, raccomando di esporre solo le porte di cui la tua applicazione ha effettivamente bisogno. Ogni porta esposta rappresenta un potenziale vettore di attacco, quindi ridurre al minimo il numero di porte esposte segue il principio del privilegio minimo.
Gestione delle porte in fase di esecuzione
Sebbene l'istruzione EXPOSE documenti quali porte usa un container, per rendere queste porte accessibili dall'host o da altre macchine, devi pubblicarle quando avvii il container.
Ecco come associare esplicitamente una porta del container a una specifica porta dell'host:
Il flag -p (o --publish) ti permette di associare una singola porta o un intervallo di porte del container all'host.
Questo comando mappa la porta 80 all'interno del container alla porta 8081 sull'host. Dopo aver eseguito questo comando, puoi accedere al server web navigando su http://localhost:8081 nel browser.
Per comodità durante lo sviluppo, Docker fornisce il flag -P, P maiuscola o --publish-all, che pubblica automaticamente tutte le porte esposte su porte casuali con numerazione alta sull'host:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7c53d9413bf image "/docker-.…"10 s ago Up 9 s 0.0.0.0:49153->80/tcp, :::49153->80/tcp wizardlOfferto da
Qui, la porta 80 all'interno del container è mappata alla porta 49153 sull'host.
Quando lavori con servizi che usano sia TCP che UDP sulla stessa porta (come i server DNS), devi specificare il protocollo durante la pubblicazione:
docker run -p53:53/tcp -p53:53/udp dns-serverOfferto da
Orchestrazione con Docker Compose
Per applicazioni multi-container, Docker Compose offre un modo più gestibile per configurare rete e porte.
In un file YAML di Docker Compose, puoi specificare le mappature delle porte sotto la chiave ports per ciascun servizio:
services:web:image: my-image
ports:-"8081:80"-"443:443"api:build: ./api
ports:-"3000:3000"Offerto da
Docker Compose fa un'importante distinzione tra ports ed expose. La sezione ports crea mappature pubblicate delle porte accessibili dall'esterno, mentre expose rende disponibili le porte solo ai servizi collegati all'interno della stessa rete di Compose:
services:web:image: my-image
ports:-"8081:80"database:image: postgres
expose:-"5432"Offerto da
In questo esempio, il servizio web è accessibile dall'host alla porta 8081, ma il database PostgreSQL è accessibile solo agli altri servizi all'interno del file Compose, non direttamente dall'host.
Per configurazioni flessibili, soprattutto tra ambienti diversi, posso usare variabili d'ambiente nelle mappature delle porte:
services:web:image: my-image
ports:-"${WEB_PORT:-8081}:80"Offerto da
Questa sintassi mi consente di specificare la porta host tramite una variabile d'ambiente (WEB_PORT), con default a 8081 se non impostata.
Esposizione delle porte Docker - Esempio pratico
Vediamo un esempio completo di esposizione delle porte Docker per un'applicazione web con un database backend.
Immagina di costruire una semplice applicazione web composta da un servizio API Python Flask e un database PostgreSQL. Il servizio API ascolta sulla porta 5000 e PostgreSQL usa la sua porta predefinita 5432.
Ecco come potrebbe apparire la nostra semplice applicazione Flask (app.py). Questa applicazione creerà un database myapp e recupererà i dati dalla tabella items, una volta che questa tabella sarà creata all'interno del database.
from flask import Flask, jsonify
import os
import psycopg2
app = Flask(__name__)# Database connection parameters from environment variables
DB_HOST = os.environ.get('DB_HOST','db')
DB_NAME = os.environ.get('DB_NAME','myapp')
DB_USER = os.environ.get('DB_USER','postgres')
DB_PASS = os.environ.get('DB_PASSWORD','postgres')@app.route('/')defindex():return jsonify({'message':'API is running'})@app.route('/items')defget_items():# Connect to the PostgreSQL database
conn = psycopg2.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASS
)# Create a cursor and execute a query
cur = conn.cursor()
cur.execute('SELECT id, name FROM items')# Fetch results and format as list of dictionaries
items =[{'id': row[0],'name': row[1]}for row in cur.fetchall()]# Close connections
cur.close()
conn.close()return jsonify(items)if __name__ =='__main__':# Run the Flask app, binding to all interfaces (important for Docker)
app.run(host='0.0.0.0', port=5000)Offerto da
Successivamente, creerò il nostro file requirements.txt:
Ora devo creare un Dockerfile per il nostro servizio API Python:
FROM python:3.9-slimWORKDIR /app# Install dependenciesCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt# Copy application codeCOPY . .# Expose the port Flask runs onEXPOSE 5000# Command to run the applicationCMD ["python", "app.py"]Offerto da
Infine, creerò un file Docker Compose per orchestrare entrambi i servizi:
Ora posso accedere all'API su http://localhost:5000, mentre l'istanza di PostgreSQL non è direttamente accessibile dall'esterno della rete Docker, il che è una buona pratica di sicurezza per i servizi di database. Ma puoi accedere a PostgreSQL dal container in esecuzione:
docker compose exec db psql -U postgres -d myappOfferto da
Questo comando accederà alla CLI di PostgreSQL, dove posso visualizzare il database e creare una tabella items. Una volta creata, posso visualizzare i dati su http://localhost:5000/items
Come esporre più porte Docker
Se la mia applicazione Python deve esporre più porte, posso specificarle tutte nel Dockerfile:
FROM python:3.9-slimWORKDIR /appCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txtCOPY . .EXPOSE 5000 8081 9090CMD ["python", "app.py"]Offerto da
Questo Dockerfile espone:
Porta 5000 per l'applicazione Flask principale (attualmente attiva)
Porta 8081 per un potenziale dashboard di monitoraggio
Porta 9090 per una futura interfaccia di debugging
È importante notare che, sebbene io abbia esposto le porte 8081 e 9090 nel Dockerfile come documentazione, la mia attuale applicazione Flask è configurata per ascoltare solo sulla porta 5000. Le ulteriori porte esposte indicano dove potrebbero essere implementate funzionalità future.
Come pubblicare le porte esposte
Per pubblicare le porte esposte in un Dockerfile, uso il flag -p o -P quando eseguo il container:
Questo mappa la porta 5000 nel container (che è esposta nel Dockerfile e dove Flask è in ascolto) alla porta 8081 sull'host. Dopo aver eseguito questo comando, posso accedere alla mia applicazione Flask navigando su http://localhost:8081 nel browser.
Posso anche usare il flag -P per pubblicare automaticamente tutte le porte esposte su porte casuali dell'host:
5000/tcp ->0.0.0.0:32768
8081/tcp ->0.0.0.0:32769
9090/tcp ->0.0.0.0:32770Offerto da
Questo comando mostra tutte le mappature delle porte per un container specifico. Ad esempio, se la mia applicazione Flask ascolta solo sulla porta 5000 ma ho esposto più porte nel Dockerfile, docker port mi mostrerà esattamente quali porte host sono mappate a quali porte del container. Quindi, se la porta 5000 è stata mappata a 32768, posso accedere alla mia applicazione Flask su http://localhost:32768
Tecniche di diagnostica e troubleshooting
Anche con una configurazione accurata, possono sorgere problemi con il mapping delle porte in Docker. Ecco alcune tecniche che uso per diagnosticare e risolvere i problemi più comuni.
Ispezione delle mappature delle porte
Il primo passo nella diagnosi di problemi legati alle porte è verificare che le mappature siano configurate correttamente. Uso questi comandi:
Elenca tutti i container in esecuzione con le mappature delle porte:
Il comando docker inspect fornisce informazioni dettagliate, incluse le impostazioni di rete. Per concentrarti sui dettagli relativi alla rete, usa:
docker inspect --format='{{json .NetworkSettings.Ports}}'[container_id]| jqOfferto da
Se hai bisogno di un'analisi più approfondita del traffico, strumenti come tcpdump e netstat possono essere molto utili. Innanzitutto, assicurati che siano installati all'interno del container. Se il container non include già questi strumenti, puoi installarli eseguendo il seguente comando:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 000.0.0.0:5000 0.0.0.0:* LISTEN
tcp 00127.0.0.11:42265 0.0.0.0:* LISTEN
udp 00127.0.0.11:34267 0.0.0.0:*Offerto da
Questo mostra, per esempio, che l'app Flask è in ascolto su tutte le interfacce sulla porta 5000.
Per monitorare il traffico in ingresso e in uscita sull'interfaccia di rete principale del container (solitamente eth0):
dockerexec-it[container_id] tcpdump -i eth0Offerto da
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytesOfferto da
Questo comando ti permette di tracciare il traffico e identificare se le richieste raggiungono il container o se i pacchetti vengono scartati o instradati in modo errato.
Analisi delle regole iptables
Docker utilizza iptables per gestire la Network Address Translation (NAT) e controllare il flusso di traffico tra host e container. Inserisce automaticamente regole per inoltrare le porte dell'host agli IP e alle porte dei container, abilitando un accesso senza soluzione di continuità ai servizi containerizzati.
Su host Linux nativi, puoi ispezionare queste regole utilizzando comandi come:
Questo mostra come Docker mappa il traffico in ingresso su porte specifiche dell'host verso gli endpoint del container. In base al file Docker Compose visto prima, vedrai le porte inoltrate:
DNAT reindirizza il traffico dall'host al container.
RETURN garantisce il corretto instradamento del traffico interno alla rete Docker.
Tuttavia, a seconda dell'ambiente (ad esempio, Docker Desktop su Windows o WSL2), Docker può gestire il port forwarding in modo diverso e le regole iptables potrebbero non essere visibili o modificabili dall'interno del sistema. In questo caso, puoi controllare il port forwarding con il seguente comando:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 04096 *:5000 *:*
tcp LISTEN 04096 *:8081 *:*
tcp LISTEN 04096 *:9090 *:* Offerto da
Suggerimenti per il troubleshooting:
Conferma le mappature delle porte con docker ps e docker port [container].
Verifica se il firewall del sistema host o software di sicurezza stanno bloccando le porte.
Usa i log del container e strumenti di rete come netstat e tcpdump per verificare il comportamento di rete della tua applicazione.
Conclusione
Esporre le porte Docker è una competenza fondamentale che colma il divario tra l'isolamento dei container e l'usabilità pratica. In questo articolo ho spiegato come funziona il modello di networking di Docker, la differenza tra esporre e pubblicare le porte e ho fornito esempi pratici per vari scenari.
Tieni a mente questi punti chiave:
Usa EXPOSE nei Dockerfile per documentare quali porte usa la tua applicazione
Usa -p o -P quando esegui i container per rendere queste porte accessibili dall'esterno
Sfrutta Docker Compose per gestire applicazioni complesse multi-container
Usa strumenti di diagnostica per risolvere i problemi quando si presentano
Padroneggiare questi concetti e tecniche ti permetterà di progettare applicazioni containerizzate più robuste che comunicano efficacemente sia internamente sia con l'esterno. Che tu stia sviluppando una semplice applicazione web o un'architettura a microservizi complessa, una corretta gestione delle porte è fondamentale per il successo.
Poiché i container continuano a dominare le strategie moderne di deployment delle applicazioni, la capacità di gestire con sicurezza il networking e le porte di Docker rimarrà una competenza essenziale nel toolkit di ogni sviluppatore.
Per continuare a imparare, dai un'occhiata alle seguenti risorse:
Esporre una porta in Docker è un modo per documentare su quali porte la tua applicazione containerizzata è in ascolto, ma non rende la porta accessibile al di fuori del container.
Come rendo accessibile la porta di un container Docker dalla mia macchina host?⌄
Pubblichi una porta usando il flag -p con docker run o la sezione ports in Docker Compose, che mappa una porta dell'host alla porta del container.
Qual è la differenza tra `EXPOSE` e `-p` in Docker?⌄
EXPOSE si usa nel Dockerfile per dichiarare le porte a scopo di documentazione, mentre -p pubblica e mappa quelle porte per l'accesso esterno.
Posso esporre più porte per un singolo container Docker?⌄
Sì, puoi esporre più porte usando più istruzioni EXPOSE nel Dockerfile o specificando più porte nella sezione ports di Docker Compose.
Come risolvo i problemi di mapping delle porte in Docker?⌄
Usa comandi come docker ps, docker port, docker inspect e strumenti di rete all'interno del container (ad es. netstat, tcpdump) per verificare le mappature delle porte e il flusso di traffico.
Come fondatore di Martin Data Solutions e Data Scientist/ML & AI Engineer freelance, porto un portfolio vario che include Regression, Classification, NLP, LLM, RAG, reti neurali, metodi ensemble e computer vision.
Ho sviluppato con successo diversi progetti ML end-to-end, includendo data cleaning, analytics, modellazione e deployment su AWS e GCP, offrendo soluzioni efficaci e scalabili.
Ho realizzato applicazioni web interattive e scalabili con Streamlit e Gradio per casi d’uso in settori diversi.
Ho insegnato e fatto mentoring a studenti di data science e analytics, supportandone la crescita professionale con approcci di apprendimento personalizzati.
Ho progettato contenuti didattici per applicazioni di retrieval-augmented generation (RAG) su misura per le esigenze enterprise.
Ho scritto articoli tecnici di grande impatto su AI & ML, trattando temi come MLOps, database vettoriali e LLM, ottenendo un notevole coinvolgimento.
In ogni progetto che affronto, applico pratiche aggiornate di ingegneria del software e DevOps, come CI/CD, linting del codice, formattazione, monitoraggio dei modelli, tracciamento degli esperimenti e gestione robusta degli errori. Mi impegno a fornire soluzioni complete, trasformando gli insight dai dati in strategie pratiche che aiutano le aziende a crescere e a sfruttare al meglio data science, machine learning e AI.
Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Approfondisci le competenze avanzate e gli strumenti all'avanguardia che oggi rivoluzionano i ruoli dell'ingegneria dei dati con il nostro percorso Professional Data Engineer.
Quando lavori con i container Docker, uno degli aspetti più importanti che ho incontrato è abilitare la comunicazione di rete tra i container e il mondo esterno. Senza una corretta configurazione delle porte, le applicazioni containerizzate restano isolate e inaccessibili. In questo articolo ti guiderò nel processo di esposizione delle porte Docker, una competenza fondamentale per chiunque lavori con applicazioni containerizzate.
Questa guida è pensata in particolare per sviluppatori software, ingegneri DevOps e professionisti IT che devono rendere le proprie applicazioni containerizzate accessibili a utenti, ad altri servizi o a sistemi esterni. Che tu stia distribuendo un server web, una API o un database all'interno di un container, capire come esporre le porte è essenziale per costruire sistemi funzionali basati su Docker.
Al termine di questo articolo, avrai una chiara comprensione di come funziona il networking in Docker, dei diversi metodi per esporre le porte e delle tecniche pratiche per applicare questi concetti nei tuoi progetti.
Se sei alle prime armi con Docker, valuta di seguire uno dei nostri corsi, come Introduction to Docker, Containerization and Virtualization with Docker and Kubernetes, Intermediate Docker o Containerization and Virtualization Concepts.
Cosa significa esporre una porta in Docker?
Prima di entrare nei dettagli tecnici, è importante capire cosa significa esposizione delle porte nell'ecosistema Docker.
Principi di isolamento della rete dei container
I container Docker sono progettati con l'isolamento come principio fondamentale. Questo isolamento è ottenuto tramite funzionalità del kernel Linux come i namespaces e i cgroups. I namespaces forniscono isolamento dei processi, garantendo che i processi all'interno di un container non possano vedere o interagire con processi di altri container o del sistema host. I cgroups, invece, gestiscono l'allocazione delle risorse, limitando quanto CPU, memoria e altre risorse un container può consumare.
Dal punto di vista della rete, ogni container riceve il proprio namespace di rete, completo di un'interfaccia Ethernet virtuale (coppia veth). Questa interfaccia si collega di default a una rete bridge di Docker, permettendo la comunicazione tra container pur mantenendo l'isolamento dalla rete dell'host. È come se ogni container avesse il proprio indirizzo di rete privato, invisibile al mondo esterno.
Nella configurazione predefinita, un container Docker è completamente isolato. I servizi in esecuzione al suo interno possono comunicare tra loro, ma sono irraggiungibili dall'esterno del container, persino dalla macchina host. Ed è qui che l'esposizione delle porte diventa necessaria.
Expose vs publish: distinzione semantica
Quando configuri le porte in Docker, incontrerai due concetti correlati ma distinti: esporre e pubblicare le porte.
Esporre le porte è principalmente una funzionalità di documentazione. Quando esponi una porta in Docker, stai essenzialmente aggiungendo metadati all'immagine del container, indicando che l'applicazione containerizzata ascolta su porte specifiche.
Tuttavia, esporre una porta non la rende effettivamente accessibile dall'esterno del container. Serve da documentazione per gli utenti della tua immagine.
Pubblicare le porte è ciò che rende davvero i servizi containerizzati disponibili al mondo esterno. La pubblicazione crea una mappatura tra una porta sulla macchina host e una porta all'interno del container. Quando pubblichi una porta, Docker configura la rete dell'host per inoltrare il traffico dalla porta host specificata alla corrispondente porta del container.
Ecco quando usare ciascun approccio:
Come esporre le porte Docker
Ora che abbiamo capito i concetti, vediamo gli aspetti pratici dell'esposizione delle porte Docker in diversi contesti.
Strategie di dichiarazione nel Dockerfile
Il modo più basilare per esporre una porta è usare l'istruzione
EXPOSEnel tuo Dockerfile. Questa dichiara le porte che il container è progettato per utilizzare.In questo esempio, ho specificato che il container utilizzerà le porte
80e443, che sono standard per il traffico HTTP (Hypertext Transfer Protocol) e HTTPS (Hypertext Transfer Protocol Secure). Puoi anche combinarle in un'unica istruzione:Quando specifichi le porte, è buona pratica includere il protocollo, TCP (Transmission Control Protocol) o UDP (User Datagram Protocol) se la tua applicazione ne usa uno specifico:
Se non viene specificato alcun protocollo, per impostazione predefinita si assume TCP. Questo è appropriato per la maggior parte delle applicazioni web, ma servizi come il DNS (Domain Name System) o i server di gaming spesso richiedono UDP.
Dal punto di vista della sicurezza, raccomando di esporre solo le porte di cui la tua applicazione ha effettivamente bisogno. Ogni porta esposta rappresenta un potenziale vettore di attacco, quindi ridurre al minimo il numero di porte esposte segue il principio del privilegio minimo.
Gestione delle porte in fase di esecuzione
Sebbene l'istruzione
EXPOSEdocumenti quali porte usa un container, per rendere queste porte accessibili dall'host o da altre macchine, devi pubblicarle quando avvii il container.Ecco come associare esplicitamente una porta del container a una specifica porta dell'host:
Il flag
-p(o--publish) ti permette di associare una singola porta o un intervallo di porte del container all'host.Questo comando mappa la porta 80 all'interno del container alla porta 8081 sull'host. Dopo aver eseguito questo comando, puoi accedere al server web navigando su
http://localhost:8081nel browser.Per comodità durante lo sviluppo, Docker fornisce il flag
-P, P maiuscola o--publish-all, che pubblica automaticamente tutte le porte esposte su porte casuali con numerazione alta sull'host:Per scoprire quali porte host sono state assegnate, posso usare il comando
docker ps:Mostrerà un output simile a:
Qui, la porta 80 all'interno del container è mappata alla porta 49153 sull'host.
Quando lavori con servizi che usano sia TCP che UDP sulla stessa porta (come i server DNS), devi specificare il protocollo durante la pubblicazione:
Orchestrazione con Docker Compose
Per applicazioni multi-container, Docker Compose offre un modo più gestibile per configurare rete e porte.
In un file YAML di Docker Compose, puoi specificare le mappature delle porte sotto la chiave
portsper ciascun servizio:Docker Compose fa un'importante distinzione tra
portsedexpose. La sezioneportscrea mappature pubblicate delle porte accessibili dall'esterno, mentreexposerende disponibili le porte solo ai servizi collegati all'interno della stessa rete di Compose:In questo esempio, il servizio
webè accessibile dall'host alla porta 8081, ma il database PostgreSQL è accessibile solo agli altri servizi all'interno del file Compose, non direttamente dall'host.Per configurazioni flessibili, soprattutto tra ambienti diversi, posso usare variabili d'ambiente nelle mappature delle porte:
Questa sintassi mi consente di specificare la porta host tramite una variabile d'ambiente (
WEB_PORT), con default a 8081 se non impostata.Esposizione delle porte Docker - Esempio pratico
Vediamo un esempio completo di esposizione delle porte Docker per un'applicazione web con un database backend.
Immagina di costruire una semplice applicazione web composta da un servizio API Python Flask e un database PostgreSQL. Il servizio API ascolta sulla porta
5000e PostgreSQL usa la sua porta predefinita5432.Ecco come potrebbe apparire la nostra semplice applicazione Flask (
app.py). Questa applicazione creerà un databasemyappe recupererà i dati dalla tabellaitems, una volta che questa tabella sarà creata all'interno del database.Successivamente, creerò il nostro file
requirements.txt:Ora devo creare un Dockerfile per il nostro servizio API Python:
Infine, creerò un file Docker Compose per orchestrare entrambi i servizi:
In questa configurazione:
5000, rendendola accessibile dalla macchina host.5432ma non la pubblica, rendendola accessibile solo agli altri servizi all'interno della rete di Compose.5432.Per eseguire questa applicazione, usa:
Ora posso accedere all'API su
http://localhost:5000, mentre l'istanza di PostgreSQL non è direttamente accessibile dall'esterno della rete Docker, il che è una buona pratica di sicurezza per i servizi di database. Ma puoi accedere a PostgreSQL dal container in esecuzione:Questo comando accederà alla CLI di PostgreSQL, dove posso visualizzare il database e creare una tabella
items. Una volta creata, posso visualizzare i dati suhttp://localhost:5000/itemsCome esporre più porte Docker
Se la mia applicazione Python deve esporre più porte, posso specificarle tutte nel Dockerfile:
Questo Dockerfile espone:
5000per l'applicazione Flask principale (attualmente attiva)8081per un potenziale dashboard di monitoraggio9090per una futura interfaccia di debuggingÈ importante notare che, sebbene io abbia esposto le porte
8081e9090nel Dockerfile come documentazione, la mia attuale applicazione Flask è configurata per ascoltare solo sulla porta5000. Le ulteriori porte esposte indicano dove potrebbero essere implementate funzionalità future.Come pubblicare le porte esposte
Per pubblicare le porte esposte in un Dockerfile, uso il flag
-po-Pquando eseguo il container:Questo mappa la porta
5000nel container (che è esposta nel Dockerfile e dove Flask è in ascolto) alla porta8081sull'host. Dopo aver eseguito questo comando, posso accedere alla mia applicazione Flask navigando suhttp://localhost:8081nel browser.Posso anche usare il flag -P per pubblicare automaticamente tutte le porte esposte su porte casuali dell'host:
Per verificare quali porte sono state pubblicate, posso usare:
Per informazioni più dettagliate, posso usare:
Questo comando mostra tutte le mappature delle porte per un container specifico. Ad esempio, se la mia applicazione Flask ascolta solo sulla porta
5000ma ho esposto più porte nel Dockerfile, docker port mi mostrerà esattamente quali porte host sono mappate a quali porte del container. Quindi, se la porta5000è stata mappata a 32768, posso accedere alla mia applicazione Flask suhttp://localhost:32768Tecniche di diagnostica e troubleshooting
Anche con una configurazione accurata, possono sorgere problemi con il mapping delle porte in Docker. Ecco alcune tecniche che uso per diagnosticare e risolvere i problemi più comuni.
Ispezione delle mappature delle porte
Il primo passo nella diagnosi di problemi legati alle porte è verificare che le mappature siano configurate correttamente. Uso questi comandi:
Elenca tutti i container in esecuzione con le mappature delle porte:
Ottieni informazioni dettagliate su un container specifico:
Controlla le mappature delle porte per un container specifico:
Il comando docker inspect fornisce informazioni dettagliate, incluse le impostazioni di rete. Per concentrarti sui dettagli relativi alla rete, usa:
Se hai bisogno di un'analisi più approfondita del traffico, strumenti come
tcpdumpenetstatpossono essere molto utili. Innanzitutto, assicurati che siano installati all'interno del container. Se il container non include già questi strumenti, puoi installarli eseguendo il seguente comando:Per vedere su quali porte l'applicazione è in ascolto all'interno del container:
Questo mostra, per esempio, che l'app Flask è in ascolto su tutte le interfacce sulla porta
5000.Per monitorare il traffico in ingresso e in uscita sull'interfaccia di rete principale del container (solitamente eth0):
Questo comando ti permette di tracciare il traffico e identificare se le richieste raggiungono il container o se i pacchetti vengono scartati o instradati in modo errato.
Analisi delle regole iptables
Docker utilizza
iptablesper gestire la Network Address Translation (NAT) e controllare il flusso di traffico tra host e container. Inserisce automaticamente regole per inoltrare le porte dell'host agli IP e alle porte dei container, abilitando un accesso senza soluzione di continuità ai servizi containerizzati.Su host Linux nativi, puoi ispezionare queste regole utilizzando comandi come:
Questo mostra come Docker mappa il traffico in ingresso su porte specifiche dell'host verso gli endpoint del container. In base al file Docker Compose visto prima, vedrai le porte inoltrate:
Qui:
DNATreindirizza il traffico dall'host al container.RETURNgarantisce il corretto instradamento del traffico interno alla rete Docker.Tuttavia, a seconda dell'ambiente (ad esempio, Docker Desktop su Windows o WSL2), Docker può gestire il port forwarding in modo diverso e le regole
iptablespotrebbero non essere visibili o modificabili dall'interno del sistema. In questo caso, puoi controllare il port forwarding con il seguente comando:Suggerimenti per il troubleshooting:
docker psedocker port [container].netstatetcpdumpper verificare il comportamento di rete della tua applicazione.Conclusione
Esporre le porte Docker è una competenza fondamentale che colma il divario tra l'isolamento dei container e l'usabilità pratica. In questo articolo ho spiegato come funziona il modello di networking di Docker, la differenza tra esporre e pubblicare le porte e ho fornito esempi pratici per vari scenari.
Tieni a mente questi punti chiave:
EXPOSEnei Dockerfile per documentare quali porte usa la tua applicazione-po-Pquando esegui i container per rendere queste porte accessibili dall'esternoPadroneggiare questi concetti e tecniche ti permetterà di progettare applicazioni containerizzate più robuste che comunicano efficacemente sia internamente sia con l'esterno. Che tu stia sviluppando una semplice applicazione web o un'architettura a microservizi complessa, una corretta gestione delle porte è fondamentale per il successo.
Poiché i container continuano a dominare le strategie moderne di deployment delle applicazioni, la capacità di gestire con sicurezza il networking e le porte di Docker rimarrà una competenza essenziale nel toolkit di ogni sviluppatore.
Per continuare a imparare, dai un'occhiata alle seguenti risorse: