5.6 KiB
Networking
Concetti base
I container, per impostazione predefinita, sono completamente isolati dal sistema host e tra di loro. Per consentire la comunicazione tra i container e il sistema host, è necessario aprire esplicitamente una determinata porta, rendere disponibile una specifica risorsa, ecc.
Per esporre una porta, si utilizza l'opzione -p
con la seguente sintassi:
docker run -d -p 8080:80 nginx
In questo esempio, la porta 80 del container viene mappata sulla porta 8080 del sistema host. Ciò significa che le richieste inviate alla porta 8080 dell'host verranno inoltrate alla porta 80 del container, dove il servizio nginx è in ascolto.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f00ddc2a0b6a nginx "/docker-entrypoint.…" 13 seconds ago Up 13 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp interesting_meninsky
Se si desidera servire contenuti web, è possibile utilizzare l'opzione -v
(volume) per mappare un contenuto all'interno del container. La sintassi è simile alla precedente:
docker run -d -p 8080:80 -v /path/to/my/webcontent:/usr/share/nginx/html nginx
In questo caso, il contenuto presente nella directory /path/to/my/webcontent
del sistema host sarà disponibile all'interno del container nella directory /usr/share/nginx/html
.
Tipologie
Esistono diverse tipologie di networking che possono essere utilizzate in Docker, denominate driver
. I tre driver principali sono:
host
: in questa modalità, il container condivide l'interfaccia di rete con il sistema host. Non vi è alcun isolamento, pertanto qualsiasi processo eseguito all'interno del container ha accesso diretto alla rete dell'host. Questo tipo di accesso alla rete è analogo a quello di un browser web su un sistema operativobridge
: questo driver fornisce isolamento tra l'host e i container, consentendo la creazione di reti virtuali. Tali reti operano in uno spazio di indirizzamento separato rispetto al sistema host e alla rete fisica, permettendo ai container di comunicare tra loro in modo privato o semi-privato. Questa modalità è la più comune e preferita per la maggior parte delle applicazioni Dockernull
: in questa configurazione, il container è completamente isolato dalla rete, non avendo alcuna connettività di rete disponibile
Port mapping
Il seguente stack di esempio è composto da due servizi: php e nginx. In particolare, il servizio nginx espone due porte: la porta 80 del container sulla porta 8080 del sistema host e la porta 443 del container sulla porta 8443 dell'host.
services:
php:
image: 'php:8.1-fpm'
container_name: ${APP_NAME:?err}-php
volumes:
- './app:/var/www/html'
nginx:
image: 'nginx:latest'
container_name: ${APP_NAME:?err}-nginx
ports:
- '8081:80'
- '8443:443'
volumes:
- './app:/var/www/html'
- './config/nginx:/etc/nginx/conf.d'
Se si avvia lo stack con il comando docker compose up -d
, il comando docker ps
conferma che nginx è in esecuzione e in ascolto su tutte le interfacce di rete (0.0.0.0
) alla porta 8080.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
73a0991fb71b nginx:latest "/docker-entrypoint.…" 3 seconds ago Up 3 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp eager_northcutt
Accedendo a localhost:8080
, è possibile raggiungere il sito web servito dallo stack. Tuttavia, questo consente anche a chiunque si trovi sulla stessa rete o, se presente il NAT sul router, a chiunque conosca l'indirizzo IP del sistema host di accedere al servizio.
Per limitare l'accesso al servizio nginx in modo che sia raggiungibile solo dal sistema host, è necessario modificare la configurazione dello stack affinché ascolti solo su localhost e non su tutte le interfacce di rete:
nginx:
image: 'nginx:latest'
container_name: ${APP_NAME:?err}-nginx
ports:
- '127.0.0.1:8081:80'
- '127.0.0.1:8443:443'
Se non è importante che le porte associate sul sistema host siano sempre le stesse, è possibile allocarle dinamicamente, in modo da sceglierne sempre una disponibile, evitando conflitti:
nginx:
image: 'nginx:latest'
container_name: ${APP_NAME:?err}-nginx
ports:
- '80'
- '443'
Le porte sono ora allocate in modo casuale:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
654f739ce935 nginx:latest "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:32770->80/tcp, [::]:32770->80/tcp crazy_jackson
Se si desidera che Docker assegni automaticamente una porta disponibile in localhost
, è possibile utilizzare la seguente sintassi:
services:
nginx:
image: 'nginx:latest'
container_name: ${APP_NAME:?err}-nginx
ports:
- '127.0.0.1:0:80' # Assegna una porta casuale su localhost
In questo caso, 127.0.0.1:0
indica a Docker di scegliere automaticamente una porta disponibile sul sistema host, associandola alla porta 80 del container:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6559daa92656 nginx:latest "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 127.0.0.1:32769->80/tcp nginx