Port forwarding con Docker

Spread the love

La mappatura delle porte Docker, nota anche come port forwarding , è una tecnica utilizzata per esporre i servizi di rete – che sono in esecuzione all’interno di un contenitore Docker – verso l’host, verso altri contenitori Docker dello stesso host o verso altri host o dispositivi di rete.

Il port forwarding consente di mappare una porta specifica dal sistema host a una porta sul contenitore, rendendo il servizio accessibile dall’esterno del contenitore.

Quando si esegue un contenitore, in genere esiste un proprio spazio dei nomi di rete isolato con il proprio indirizzo IP (per questo, si veda il comando docker network). Per impostazione predefinita, i contenitori possono comunicare tra loro e con il sistema host, ma l’accesso alla rete esterna non è abilitato automaticamente. La mappatura delle porte viene utilizzata per creare la comunicazione tra la rete isolata del contenitore e la rete del sistema host.

La mappatura delle porte

Possiamo eseguire la mappatura delle porte in Docker in due modi: usando il Dockerfile e i comandi di docker, oppure con docker-compose.

Quando si esegue un contenitore con docker run.

Quando si utilizza il comando docker run, è possibile utilizzare il flag -p--publishper specificare la mappatura delle porte. La sintassi è la seguente: -p host_port:container_port. Ad esempio, per mappare:

  • la porta 3307 sull’host
  • alla porta 3306 all’interno del contenitore,

Quindi: -p 3307:3306. È possibile specificare più mappature di porte ripetendo il flag -p. Questo per esempio ci serve se nello stesso container vogliamo pubblicare un database, un web server Apache o un Tomcat.

# docker run - p 8080:80 myapp

Quando si utilizza docker compose:

Se si utilizza Docker Compose per gestire i contenitori, si può puoi definire la mappatura delle porte nel file di configuazione docker-compose.yml utilizzando la sezione portssezione. La sintassi è la stessa del comando docker run.

Nel mio caso ho un container che contiene un’applicazione PHP – Laravel e una che contiene il DBMS MySQL:

version: '3'

services:
  app:
    image: ap2mylaravel
    container_name: app
    networks:
      - my_network

  mysql_db_container:
    image: mysql_db
    container_name: app_db
    ports:
      - "3307:3306" # Mappa la porta 3306 del container sulla porta 3307 dell'host
    networks:
      - my_network

networks:
  my_network:
     driver: bridge

Il container che ospita MySQL si intende pubblicato sulla porta interna 3306 che, all’esterno dell’host, viene mappata sulla 3307 (per non confliggere con quella del MySQL che gira sull’host che è pubblicato sulla 3306).

Il comando

# docker-compose up

avvierà il contenitore con la mappatura della porta specificata.

Ho disegnato questo schema funzionale completo in cui si vede come vanno usati i comandi per collegarsi al container del db a partire dall’altro container, dall’host e anche da un computer remoto: si vedono i due container che giurano all’interno di Host, il container dedicato al dbms ascolta sulla porta 3306 e internamente a Host ed è questa la porta che va usata nei client (sia che si utilizzi il calinet in Host che nel container app.

Posso altresì accedere allo stesso db anche dall’esterno del host – un pc remoto – puntando alla porta 3307 e utilizzando l’indirizzo del netowk virtuale creato da docker che posso trovare digitanto docker network ls (posso verificare che l’interfaccia è proprio quella che si vede digitando il comando ifconfig).

È possibile configurare la rete (sia agendo a livello di configurazione docker che sulla configurazione di mysql) in modo tale da avere il livello di sicurezza che si vuole: per esempio ho fatto in modo che l’accesso al dbms come root sia possibile esclusivamente dall’interno del container app_db e che laravel possa accedere soltanto dal suo container (app) con un utente applicativo a cui sono stati concessi i soli privilegi di crud.

docker network layout
docker network layout

Riferimenti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.