Come utilizzare docker-compose con Podman su Linux
Podman è un'alternativa gratuita e open source a Docker, creata da Red Hat. Sebbene Docker sia probabilmente più diffuso, al punto da diventare sinonimo di “contenitori”, dal punto di vista tecnico Podman è superiore: è stato progettato, fin dall’inizio, per essere daemonless, è in grado di funzionare senza la necessità di privilegi di root ed è meglio integrato nell'ambiente Linux. Una delle cose che potenzialmente ha impedito a molti di migrare da Docker a Podman era la mancanza di un equivalente Podman a tutti gli effetti per docker-compose. Creando un livello di compatibilità tra Podman e Docker, ora è effettivamente possibile utilizzare Docker-Compose come se fosse uno strumento nativo di Podman.
In questo tutorial vediamo come installare docker-compose sulle distribuzioni Linux più utilizzate, e come utilizzarlo con Podman invece che con Docker.
In questo tutorial imparerai:
- Come installare podman, podman-docker e docker-compose sulle distribuzioni Linux più utilizzate
- Come configurare Podman per funzionare con docker-compose
- Come utilizzare docker-compose con Podman
Installazione di pacchetti
La prima cosa che dobbiamo fare, per poter utilizzare docker-compose con Podman, è installare il pacchetto podman-docker. Questo pacchetto fornisce un livello di compatibilità tra Docker e Podman, emulando la CLI Docker, ma eseguendo i comandi Podman, dietro le quinte.
Per eseguire l'installazione su Fedora e altre distribuzioni della famiglia Red Hat, possiamo eseguire:
$ sudo dnf install podman podman-docker
Per installare il pacchetto su Debian e distribuzioni basate su Debian, invece, possiamo eseguire:
$ sudo apt install podman podman-docker
Installazione di docker-compose
Ora dobbiamo installare docker-compose. Attualmente esistono due versioni di docker-compose: la prima, “v1”, è la versione originale e ora deprecata scritta in Python, che riceve solo correzioni di sicurezza. Il secondo, "v2", è scritto in Go, è sviluppato attivamente ed è confezionato come plug-in Docker nei repository ufficiali Docker.
Installazione di docker-compose v1
La maggior parte delle distribuzioni Linux includono un pacchetto “docker-compose” che fornisce la versione Python dello strumento. Per installarlo su Fedora, eseguiamo:
$ sudo dnf install docker-compose
Su RHEL e cloni il pacchetto docker-compose non è disponibile immediatamente, né può essere installato (almeno al momento in cui scrivo) dal repository EPEL. Su queste distribuzioni, dobbiamo installare docker-compose v1 come pacchetto Python con pip, il gestore di pacchetti Python.
Poiché non vogliamo eseguire pip come root, installiamo il pacchetto nel suo ambiente virtuale dedicato, come utente standard e non privilegiato, e quindi creiamo un collegamento simbolico all'eseguibile (in alternativa possiamo utilizzare uno strumento come pipx). Nell'esempio seguente, presumo che la directory ~/.local/bin
esista e si trovi nel nostro PERCORSO:
$ python3 -m venv virtualenv
$ virtualenv/bin/pip install docker-compose
$ ln -s "${PWD}/virtualenv/bin/docker-compose" ~/.local/bin/docker-compose
Per installare docker-compose v1 su Debian e distribuzioni basate su Debian, possiamo eseguire:
$ sudo apt install docker-compose
Installazione di docker-compose v2
Come abbiamo già detto, la versione ufficiale supportata e sviluppata attivamente di docker-compose è la v2. Un modo universale e trasversale per installarlo è scaricare il binario precompilato per la nostra architettura di sistema, direttamente dal repository GitHub del progetto. Nell'esempio seguente scarichiamo la versione Linux x86_64 dell'ultima release (2.27 al momento in cui scriviamo):
$ curl -LO https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-x86_64
Dopo aver scaricato il binario, lo rendiamo eseguibile, quindi lo spostiamo in una directory nel nostro PERCORSO. Per installarlo solo per il nostro utente possiamo spostarlo in ~/.local/bin
, per installarlo a livello di sistema, invece, possiamo spostarlo in /usr/local/bin :
$ chmod +x docker-compose-linux-x86_64
$ sudo mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
Un modo alternativo per installare docker-compose v2 è dal repository Docker ufficiale. Per prima cosa aggiungiamo il repository alla nostra distribuzione, seguendo la guida ufficiale, poi installiamo il pacchetto “docker-compose-plugin”:
$ sudo dnf install docker-compose-plugin
Quando eseguiamo il comando sopra, installiamo docker-compose come plugin Docker piuttosto che come binario autonomo: per usarlo come tale, è sufficiente creare un collegamento simbolico in una directory nel nostro PATH:
$ sudo ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose
Abilitazione e avvio del socket Podman
Una delle principali differenze tra Podman e Docker è il loro design. Docker utilizza un'architettura client-server: il demone Docker viene eseguito in background, normalmente con privilegi di root (sebbene le versioni recenti di Docker supportino l'esecuzione di una versione del demone senza root, a livello utente), mentre Podman utilizza il cosiddetto "fork-exec" " (ogni contenitore viene eseguito come processo figlio Podman). Poiché docker-compose è pensato per funzionare con Docker, si aspetta che il demone docker sia in esecuzione. Per questo motivo, Podman fornisce l'unità systemd “podman.socket”. Per utilizzare docker-compose con Podman è necessario avviarlo e abilitarlo:
$ sudo systemctl enable --now podman.socket
Se vogliamo utilizzare docker-compose con un'istanza Podman senza root, dobbiamo abilitare e avviare un'istanza del socket a livello utente:
$ systemctl --user enable --now podman.socket
In quest'ultimo caso, dobbiamo anche definire ed esportare la variabile d'ambiente DOCKER_HOST
. Il modo tradizionale per farlo è aggiungere la riga seguente a ~/.bash_profile
o ~/.profile
, a seconda della shell che stiamo utilizzando:
export DOCKER_HOST=unix:///run/user/1000/docker.sock
Per rendere le modifiche immediatamente effettive nella nostra attuale istanza di shell, senza attendere il prossimo accesso, possiamo procurarci direttamente il file:
$ source ~/.bash_profile
Socket Systemd rispetto al servizio
Oltre all'unità socket che abbiamo attivato nel passaggio precedente (/usr/lib/systemd/system/podman.socket
), il pacchetto Podman viene fornito con un'unità di “servizio” systemd (/usr/ lib/systemd/system/podman.service
); cosa realizza effettivamente questo servizio e perché utilizziamo l'unità socket e non direttamente il servizio?
Per vedere il comando che Systemd esegue quando avvia il servizio Podman, è sufficiente dare un'occhiata all'unità stessa. Ciò che ci interessa, in questo caso, è il valore dell’opzione “ExecStart”, nella sezione “Servizio”:
ExecStart=/usr/bin/podman $LOGGING system service
Possiamo vedere che all'avvio del servizio, Systemd esegue il comando podman system service
. Ciò che fa questo comando è creare un servizio di ascolto che risponda alle chiamate API per Podman. In questo modo, sebbene Podman non abbia bisogno di un demone per funzionare, Podman può “imitare” l’interfaccia Docker.
Perché abilitiamo e avviamo l'unità socket, invece del servizio direttamente? In questo modo sfruttiamo una funzionalità di Systemd: i servizi attivati tramite socket. Il socket ascolta le connessioni e avvia il servizio su richiesta, utilizzando le risorse nel modo più efficiente.
Utilizzando docker-compose
Una volta che tutto è a posto, possiamo usare docker-compose come se eseguissimo Docker sotto il cofano. Quello seguente è un esempio base di un file di composizione. Genera un contenitore per un server MariaDB e uno per phpMyAdmin:
version: '3.7'
services:
mariadb:
image: docker.io/mariadb
volumes:
- db:/var/lib/mysql
environment:
TZ: "Europe/Rome"
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_USER: testuser
MYSQL_PASSWORD: testpassword
MYSQL_DATABASE: testdb
phpmyadmin:
image: docker.io/phpmyadmin
environment:
PMA_HOST: mariadb
ports:
- "80:80"
depends_on:
- mariadb
volumes:
db:
Per creare i contenitori, i volumi e una rete dedicata per lo stack, eseguiamo:
$ sudo docker-compose up
Conclusioni
In questo tutorial abbiamo imparato come configurare Podman per lavorare con docker-compose. Docker-compose è stato progettato per funzionare con Docker che, a differenza di Podman, utilizza un'architettura client-server. Abilitando il socket Podman e installando il pacchetto podman-docker, creiamo sostanzialmente un livello di compatibilità che ci consente di utilizzare in modo trasparente docker-compose con Podman.