Skip to content

Instantly share code, notes, and snippets.

@luca-c-xcv
Last active February 13, 2022 00:49
Show Gist options
  • Save luca-c-xcv/7a71bc8b37cf0d2a09528a9da61f665d to your computer and use it in GitHub Desktop.
Save luca-c-xcv/7a71bc8b37cf0d2a09528a9da61f665d to your computer and use it in GitHub Desktop.
Manabile per Docker

Manabile Docker

Indice


Introduzione

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.


Immagine

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à.


Dockerfile

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.

Istruzioni

FROM

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.

RUN

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"]
CMD

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

LABEL

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."
EXPOSE

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
ENV

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
ADD

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>"]
COPY

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>"]
ADD vs COPY

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.

ENTRYPOINT

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
VOLUME

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
USER

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>]
WORKDIR

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
Altro

Per più informazioni e ulteriori comandi consultare il manuale al seguente indirizzo: DockerDocs

Esempio

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

Docker Compose

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).

Opzioni

version

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.

services

Questa è la seconda riga che deve essere scritta e dichiara che i campi successivi sono i container che devono essere creati.

build

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
container_name

Istanza utile per specificare il nome del container.

container_name: my-container
depends_on

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
restart_policy

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
env_file

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
environment

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:
image

Specifica l'immagine che verrà usata per la creazione del container

image: redis
network_mode

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"
networks

Specifica le reti usabili dal container. NON UTILIZZABILE IN MODALITÀ HOST.

networks:
      some-network:
        aliases:
          - alias1
          - alias3
      other-network:
        aliases:
          - alias2
ports

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"
restart

Specifica la politica di riavvio del container nel caso in cui venisse stoppato.

restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
volumes

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
Altro

Per maggiori informazioni e ulteriori istruzioni consultare: Docker Compose

Esempio

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
@luca-c-xcv
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment