+++ title = "Docker per principianti" outputs = ["Reveal"] +++ # Docker ## Cos'e': * una piattaforma aperta per costruire, distribuire ed eseguire applicazioni all'interno di container * esiste per linux/mac/windows * i container non sono macchine virtuali, ad es. condividono la RAM e il kernel col sistema che li ospita * sono pero' "isolati" dal sistema sottostante grazie a due funzioni del kernel: Control Groups (Cgroups) e Namespaces --- # Concetti base ## Immagini * Un'immagine docker e' un template in sola lettura * Esiste un Docker Hub, un repository di immagini gia' pronte * Si possono costruire facilmente immagini basandosi su immagini pre-esistenti (es. debian-mini) a cui posso aggiungere un singolo pacchetto * le immagini hanno delle tag associate, per cui ad es. possono esistere diverse "versioni" di una certa immagine, ad es. php:5 e php:7 o anche debian:stretch e debian:buster --- # Concetti base ## Container * Un container e' una "istanza" di una immagine * Un container in genere esegue un solo processo (es. apache) * Quindi ad esempio se si vuole un CMS servono almeno 2 container: uno per il webserver e uno per il database * I container possono comunicare tra di loro tramite un'interfaccia di rete * I container possono comunicare allo stesso modo anche con l'host, per cui ad esempio potrei avere il webserver in un container e il database sull'host --- # Componenti base ## Docker Engine * Docker e' un'applicazione client/server * il Docker Engine e' il demone che controlla l'esecuzione dei containers, e gira coi permessi di root. * esiste un file di configurazione in /etc/docker/daemon.json --- # Docker client il client e' l'interfaccia (testuale) per fare tutto, dalla costruzione delle immagini all'esecuzione dei containers. esistono intefacce grafiche, ma sono poco utili per imparare a usare docker. --- ## comandi per le immagini * docker search - cerca una immagine nel docker hub * docker pull - scarica un'immagine es. docker pull hello-world * docker images - lista le immagini presenti nel nostro sistema * docker rmi nomeimmagine - elimina una immagine dal disco --- ``` (~)# docker search nextcloud NAME DESCRIPTION STARS OFFICIAL AUTOMATED nextcloud A safe home for all your data 1492 [OK] linuxserver/nextcloud A Nextcloud container, brought to you by Lin… 239 wonderfall/nextcloud All-in-one alpine-based Nextcloud image. 82 [OK] greyltc/nextcloud Nextcloud: a safe home for all your data. De… 39 [OK] ownyourbits/nextcloudpi-armhf NextCloudPi ARM docker container 28 ownyourbits/nextcloudpi NextCloudPi Docker container (all architectu… 12 ownyourbits/nextcloudpi-x86 NextCloudPi x86 docker container 12 ``` --- ``` (~)$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE nextcloud 18 30510f8fb18b 24 hours ago 726MB nextcloud 17 b158dd64c9a3 2 months ago 724MB wallabag/wallabag latest 89208e55d00c 5 months ago 482MB putro/web2py latest 65ec2a7db4f2 7 months ago 607MB putro/apache-php latest 958bf6f8388e 8 months ago 273MB bitnami/minideb buster 0e45c7c725a0 8 months ago 67.5MB bitnami/minideb stretch 04c0a4570b8c 13 months ago 53.7MB postgres latest 79db2bf18b4a 10 months ago 312MB x86dev/docker-ttrss latest dab1dd3dcc68 11 months ago 94.1MB putro/taskd 0.1 a7aec0dc9429 13 months ago 78.4MB ``` --- ## comandi per i container * docker ps - mostra i container in esecuzione * docker ps -a - mostra i container in esecuzione e quelli fermi * docker rm ID - elimina il container ID (funziona solo per quelli fermi) * docker start/stop ID avvia un container fermo o ne ferma uno in esecuzione * docker logs (-f) ID - mostra i log di un container --- ``` (~)$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4d6cce1d9768 b158dd64c9a3 "/entrypoint.sh apac…" 2 months ago Up 2 months 80/tcp nextcloud 1bcc9ddd624b wallabag/wallabag:latest "/entrypoint.sh wall…" 5 months ago Up 5 months 80/tcp wallabag a2627194dc0a a7aec0dc9429 "/run.sh" 7 months ago Up 5 months 0.0.0.0:53589->53589/tcp taskd 632a922e55f9 putro/apache-php "/usr/bin/apache2-fo…" 8 months ago Up 7 months 80/tcp, 443/tcp, 8080/tcp apache cfa463df8e9d x86dev/docker-ttrss "/init" 11 months ago Up 7 months 4443/tcp, 8080/tcp ttrss 06d25d8acea4 postgres:latest "docker-entrypoint.s…" 13 months ago Up 7 months 5432/tcp postgres 5ca30876c4b2 jojomi/hugo:latest "/run.sh" 52 minutes ago Exited (137) 39 minutes ago hugo ``` --- ## docker run fa partire un processo dentro un nuovo container partendo dall'immagine specificata, es. docker run hello-world se non si specifica un nome il container avra' un nome casuale, altrimenti usare --name nomescelto ci sono un sacco di opzioni, vedi man docker-run, perche' questo e' il comando con cui si fa partire un container e si specificano tutti i "parametri" --- ## hello-world questa e' un'immagine minimale, contiene solo un eseguibile che viene lanciato all'avvio, che stampa un testo e poi esce quando il processo lanciato all'avvio del container esce, il container si spegne perche' non c'e' piu' nulla in esecuzione. **Un container esegue un solo processo** **un'immagine docker e' "programmata" per eseguire un solo comando quando avvia un container** Se e' necessario eseguire piu' processi dentro un container bisogna usare qualcosa tipo supervisord, cioe' un programma che una volta lanciato puo' fare cose e resta in esecuzione. --- ## docker exec esegue un comando dentro un container in esecuzione, es. docker exec -it /bin/sh mysql in questo modo ci si ritrova in una shell sh **dentro** il container mysql in esecuzione. --- ## La persistenza dei dati i container non devono **MAI** contenere dati volatili perche' i dati non sopravvivono alla distruzione o riavvio di un container #### come gestire i dati dentro i container: * bind-mount di una cartella sull'host dentro il container * docker volumes (stanno in /var/lib/docker/volumes) --- ## docker network i container possono sempre comunicare tra di loro tramite un'interfaccia bridged docker0 (su linux) mentre di default non sono raggiungibili dall'esterno. per rendere un container visibile pubblicamente si puo': * mettergli un reverse-proxy davanti (es. nginx, anche dockerizzato a sua volta) * mappare una porta dell'host su una porta del container e' comunque possibile creare reti e assegnare indirizzi IP ai container --- ## Dockerfile * e' un file "ricetta" per creare una nuova immagine (con docker build) * definisce come creare l'immagine (da dove partire e cosa aggiungere (files e pacchetti) * definisce alcune configurazioni dell'immagine (es. che porta di rete aprire all'esterno) * definisce cosa eseguire all'avvio * in genere su hub.docker.com sono disponibili i Dockerfile con cui si sono create le immagini --- ##### esempio di Dockerfile per costruire un'immagine nginx ``` FROM bitnami/minideb:buster MAINTAINER Mario Rossi (mario.rossi@diocovid.xxx) RUN apt-get update RUN apt-get install -y nginx COPY index.html /var/www/html/ ENTRYPOINT [“/usr/sbin/nginx”,”-g”,”daemon off;”] EXPOSE 80 ``` docker run -d -p 80:80 --name webserver myimage --- ## docker-compose * e' un software che permette di leggere un file di configurazione per avviare containers * non fa parte di docker, va scaricato a parte * la sua sintassi e' variata nel tempo, infatti il docker-compose.yml riporta sempre la versione * permette di definire variabili, porte, volumi, reti per avviare containers. * semplifica l'uso di "docker run" --- https://hub.docker.com/_/nextcloud/ ``` version: '2' volumes: nextcloud: db: services: db: container_name: database image: mariadb restart: always volumes: - db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=rootpwd - MYSQL_PASSWORD=nextcloudpwd - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud app: image: nextcloud:18 container_name: nextcloud ports: - 8080:80 links: - db volumes: - nextcloud:/var/www/html restart: always ``` docker-compose up -d --- # FINE