Docker è un sistema di containerizzazione di servizi/processi. Differisce dalla macchina virtuale per il fatto che il container non contiene il sistema operativo completo ma solo le librerie necessarie ad eseguire il/i processo/i. Usando quest'informazione quindi è possibile dire che un container è un processo isolato da tutti gli altri del sistema avendo un proprio ambiente di esecuzione con proprie variabili d'ambiente e proprie librerie. Inoltre Docker fornisce un sistema per gestire anche le reti e i volumi del container.
I container Docker sono gestibili direttamente da terminale o attraverso dei file componibili che aiutano nella creazione del container (Dockerfile) e nella gestione di vari container appartenenti alla solita applicazione.
Un immagine Docker è un oggetto contenente tutte le informazioni e librerie necessarie per la creazione di un container. Possiamo vedere un'immagine come un insieme di regole e direttive necessarie alla creazione del container vero e proprio, difatti l'immagine non è istanziabile ma al contrario può istanziare uno o più container. Le immagini possono essere generate da un Dockerfile oppure possono essere scaricate già complete da DockerHub. Un ulteriore sistema per la creazione d'immagini è quella di scaricare immagini da DockerHub modificando o aggiungendo funzionalità.
Il Dockerfile è un file di testo al cui interno è possibile inserire comandi da far eseguire a Docker durante la creazione dell'immagine. La prima direttiva necessaria, quella che apre il file, è la FROM che è necessaria per dire a Docker su quale sistema o immagine si deve basare per la creazione della nuova immagine.
L'istruzione FROM inizializza una nuova fase di compilazione e imposta l'immagine di base per le istruzioni successive. Come tale, un Dockerfile valido deve iniziare con un'istruzione FROM. L'immagine può essere qualsiasi immagine valida - è particolarmente facile iniziare prendendo un'immagine dai repository pubblici.
ARG è l'unica istruzione che può precedere FROM nel Dockerfile. [...]
Da quanto scritto nel manuale di Docker si può capire che tale istruzione deve essere esguita per prima e quindi debba essere all'inizio del Dockerfile, anche se ARG
può procedere FROM
, ma è l'unica istruzione, in quanto definisce solo delle variabili che possono essere riutilizzate nel Dockerfile dopo la FROM.
FROM può apparire più volte all'interno di un singolo Dockerfile per creare più immagini o usare una fase di compilazione come dipendenza per un'altra. Ogni istruzione FROM cancella qualsiasi stato creato dalle istruzioni precedenti.
Il flag opzionale --platform
può essere usato per specificare la piattaforma dell'immagine nel caso FROM
faccia riferimento a un'immagine multipiattaforma. Per esempio, linux/amd64, linux/arm64, o windows/amd64.
L'istruzione RUN eseguirà tutti i comandi in un nuovo livello sopra l'immagine corrente e commetterà i risultati. L'immagine impegnata risultante sarà usata per il passo successivo nel Dockerfile. Stratificare le istruzioni RUN e generare i commit è conforme ai concetti fondamentali di Docker, dove i commit sono economici e i container possono essere creati da qualsiasi punto della storia di un'immagine, un po' come il controllo dei sorgenti.
Quest'istruzione esegue il comando che gli viene passato per poi poter utilizzare il risultato nelle fasi successive del Dockerfile. Quest'istruzione può essere scrittà in due modi diversi:
RUN <comando>
RUN ["<eseguibile>", "argomento1", "argomentoN"]
Ci può essere solo un'istruzione CMD in un Dockerfile. Se elenchi più di un CMD, solo l'ultimo CMD avrà effetto.
Lo scopo principale di un CMD è quello di fornire le impostazioni predefinite per un contenitore in esecuzione. Queste impostazioni predefinite possono includere un eseguibile, o possono omettere l'eseguibile, nel qual caso è necessario specificare anche un'istruzione ENTRYPOINT.
Se CMD è usato per fornire argomenti predefiniti per l'istruzione ENTRYPOINT, entrambe le istruzioni CMD ed ENTRYPOINT dovrebbero essere specificate con il formato array JSON.
Questa istruzione è l'ultima istruzione che deve essere eseguita in quanto è quella che viene eseguita per lanciare il processo principale all'interno del container, per questo motivo ci deve essere una sola istanza di questa istruzione, in caso contrario verrà eseguita solo l'ultima. Si può scrivere in 3 modi differenti:
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
Il secondo modo è utilizzabile per l'entrypoint, verrà eseguito l'entrypoint.sh
con i paramentri passati nel comando CMD
L'istruzione LABEL aggiunge metadati ad un'immagine. Un LABEL è una coppia chiave-valore. Per includere spazi all'interno di un valore LABEL, usa le virgolette e i backslash come faresti nell'analisi della riga di comando
Quest'istruzione imposta i metadati all'immagine, viene usata in genere per impostare il maintainer, la versione o altre informazioni secondarie utili per manutenibilità
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
L'istruzione EXPOSE informa Docker che il contenitore ascolta le porte di rete specificate in fase di esecuzione. È possibile specificare se la porta ascolta su TCP o UDP, e il default è TCP se il protocollo non è specificato.
EXPOSE
apre la porta di docker per poter far comunicare il container con il mondo esterno. Ovviamente la porta del processo interno dovrà essere la solita che è inserita in EXPOSE
.
EXPOSE port/protcol
EXPOSE port
L'istruzione ENV imposta la variabile d'ambiente al valore . Questo valore sarà nell'ambiente per tutte le istruzioni successive nella fase di compilazione e può essere sostituito in linea anche in molte altre. Il valore sarà interpretato per altre variabili d'ambiente, quindi i caratteri di virgolette saranno rimossi se non sono sfuggiti. Come per l'analisi della linea di comando, le virgolette e i backslash possono essere usati per includere spazi all'interno dei valori.
Con questa istruzione è possibile settare le variabili d'ambiente del container, per poi essere utilizzate dal container stesso o dai servizi interni.
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
L'istruzione ADD copia nuovi file, directory o URL di file remoti da e li aggiunge al filesystem dell'immagine al percorso . Possono essere specificate più risorse , ma se sono file o directory, i loro percorsi sono interpretati come relativi alla sorgente del contesto di compilazione.
ADD
aggiunge file(s) dall'host all'immagine per poi essere usato nel container.
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
L'istruzione COPY copia nuovi file o directory da e li aggiunge al filesystem del contenitore al percorso . Possono essere specificate più risorse , ma i percorsi dei file e delle directory saranno interpretati come relativi all'origine del contesto della costruzione.
COPY
copia file(s) dal filesystem host all'immagine.
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
A livello host e container i due comandi si equivalgono, ma ADD
ha alcune funzionalità in più come poter scaricare un file direttamente da Internet.
Un ENTRYPOINT permette di configurare un contenitore che verrà eseguito come un eseguibile.
Esegue un comando bash o un eseguibile all'interno del contenitore nel momento in cui viene lanciato il container.
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
L'istruzione VOLUME crea un punto di montaggio con il nome specificato e lo contrassegna come contenente volumi montati esternamente dall'host nativo o da altri contenitori. Il valore può essere un array JSON, VOLUME ["/var/log/"], o una semplice stringa con più argomenti, come VOLUME /var/log o VOLUME /var/log /var/db.
Quest'istruzione crea un punto di montaggio di volumi tra l'host e il container o tra containers.
VOLUME ["/data"]
VOLUME volume1 volume2
L'istruzione USER imposta il nome utente (o UID) e opzionalmente il gruppo utente (o GID) da usare quando si esegue l'immagine e per qualsiasi istruzione RUN, CMD e ENTRYPOINT che la segue nel Dockerfile.
Con questa istruzione è possibile settare l'utente con cui eseguire il processo nel container.
USER <user>[:<group>]
USER <UID>[:<GID>]
L'istruzione WORKDIR imposta la directory di lavoro per tutte le istruzioni RUN, CMD, ENTRYPOINT, COPY e ADD che la seguono nel Dockerfile. Se WORKDIR non esiste, verrà creato anche se non viene usato in nessuna istruzione Dockerfile successiva. L'istruzione WORKDIR può essere usata più volte in un Dockerfile.
WORKDIR
imposta la cartella di lavoro per usare i path relativi all'interno del Dockerfile
WORKDIR /path/to/workdir
Per più informazioni e ulteriori comandi consultare il manuale al seguente indirizzo: DockerDocs
FROM debian:latest
RUN apt-get update && apt-get install -y wget
RUN apt-get update && apt-get install -y locales
COPY ./conf/configFile.conf /home/configFile.conf
ADD ./conf/config.sh /home/config.sh
ENV LANG en_US.utf8
CMD tail -f /dev/null
Il Docker Compose
è un file YAML
in cui si possono costruire i vari container appartenenti ad una solita applicazione. Utilizzando il Docker Compose si ha la possibilità di controllare tutti i container con pochi comandi e di farli comunicare tra loro, usando direttamente il nome, attraverso una sottorete che Docker si costruisce appositamente per tale compito (senza esporre nessuna porta).
Specifica la versione di YAML
usata per specificare i campi da usare nella creazione del servizio. Questa key
deve essere la prima istanza del file.
Questa è la seconda riga che deve essere scritta e dichiara che i campi successivi sono i container che devono essere creati.
Può specificare il path della directory di lavoro o essere istanziato come oggetto da usare per specificare altri argomenti come il nome del Dockerfile
build:
context: .
dockerfile: Dockerfile-alternate
network: host
Istanza utile per specificare il nome del container.
container_name: my-container
Istanza utile per collegare a tempo di esecuzione i container. Quando specificata questa istruzione, a tempo di esecuzione verranno lanciati prima i container dichiarati all'interno di depends_on
per poi lanciare quest'ultimo.
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
Istruzione che dichiara il modo in cui il container verrà riavviato nel caso in cui stoppato per errore o altri motivi
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
Path di files in cui vengono salvati i valori delle variabili di ambiente utilizzabili nel docker-compose.
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/runtime_opts.env
Lista di variabili d'ambiente da usare all'interno del container.
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
Specifica l'immagine che verrà usata per la creazione del container
image: redis
Specifica il modo in cui il container crea la rete. Per linux è possibile usare anche la modalità host
in cui la rete è direttamente sul sistema host e non viene emulata.
network_mode: "bridge"
Specifica le reti usabili dal container. NON UTILIZZABILE IN MODALITÀ HOST.
networks:
some-network:
aliases:
- alias1
- alias3
other-network:
aliases:
- alias2
Specifica le porte che verranno usate sul container e sul sistema host. NON UTILIZZABILE IN MODALITÀ HOST
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "127.0.0.1::5000
- "6060:6060/udp"
- "12400-12500:1240"
Specifica la politica di riavvio del container nel caso in cui venisse stoppato.
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
Specifica i punti di montaggio di volumi tra container e host o containers
volumes:
- /var/lib/mysql
- /opt/data:/var/lib/mysql
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./static
target: /opt/app/static
Per maggiori informazioni e ulteriori istruzioni consultare: Docker Compose
version: '3.4'
services:
sql:
build: ./sql
image: mysql:latest
restart: always
volumes:
- ./sql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD="MYROOTPASSWORD"
hostname: sql
networks:
frontend:
nginx:
image: nginx:latest
build: ./nginx
restart: always
network_mode: host
security_opt:
- apparmor=nginx
plex:
image: ghcr.io/linuxserver/plex
environment:
- PUID=1000
- PGID=1000
- VERSION=docker
volumes:
- ./plex/database:/config
- ./plex/transcode:/transcode
- ./plex/media:/data
network_mode: host
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 10.12.2.0/26
PDF file