# Compose

`Docker Compose` è uno strumento di orchestrazione per Docker che permette di definire e eseguire applicazioni multi-container utilizzando un singolo file YAML, chiamato `docker-compose.yml`. Questo file contiene tutte le informazioni necessarie per configurare e avviare tutti i servizi dello stack applicativo, incluse le reti e i volumi.

Facilita l'avvio, l'arresto e la gestione dei container.

Come si vede dall'esempio, vi é una corrispondenza 1:1 tra i parametri della linea di comando e il file di configurazione:

```yml
services:
  php:
    image: 'php:8.1-fpm'
    container_name: php
    volumes:
      - './app:/var/www/html'

  nginx:
    image: 'nginx:latest'
    container_name: nginx
    ports:
      - 8080:80
      - 8443:443
    volumes:
      - './app:/var/www/html:ro'
      - './config/nginx:/etc/nginx/conf.d'
    depends_on:
      - php
```

È importante notare che tutti i servizi definiti nello stesso file `docker-compose.yml` sono automaticamente collocati nella stessa rete. Questo consente loro di comunicare tra loro senza la necessità di aprire porte specifiche.

Nell'esempio fornito, il container di nginx dipende da quello di php. Di conseguenza, nginx verrà avviato dopo php, garantendo che le dipendenze siano rispettate.

## Gestione dello Stack

Per avviare lo stack Docker, è sufficiente eseguire il comando `docker compose up -d` dalla stessa directory in cui si trova il file docker-compose.yml. Per arrestare i container, utilizzare invece `docker compose down`.

## Variabili d'ambiente

```yml
services:
    php:
        image: 'php:8.1-fpm'
        container_name: ${APP_NAME:?err}-php
        volumes:
            - './app:/var/www/html'

    nginx:
        image: 'nginx:latest'
        container_name: ${APP_NAME:?err}-nginx
        ports:
            - '8081:80'
            - '8443:443'
        volumes:
            - './app:/var/www/html'
            - './config/nginx:/etc/nginx/conf.d'

    mariadb:
        image: 'mariadb:latest'
        container_name: ${APP_NAME:?err}-mariadb
        restart: 'on-failure'
        environment:
            MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:?err}
```

La sintassi `${}` viene utilizzata per indicare le variabili d'ambiente nel file `docker-compose.yml`. In particolare, nel caso in cui la variabile `APP_NAME` non venga valorizzata, Docker Compose mostrerà un errore. Questa variabile sarà valorizzata all'interno del file `.env`.

L'utilizzo del file `.env` permette di separare i dati, anche quelli sensibili, dalla configurazione vera e propria, risultando in un file compose pulito, generico e riutilizzabile.

Inoltre, il parametro `environment` serve a impostare delle variabili d'ambiente che saranno esportate all'interno del container, rendendole disponibili e utilizzabili dal servizio.

## Restart policy

La politica di riavvio definisce le condizioni in cui un container deve essere riavviato dopo un arresto o un riavvio del servizio Docker. Per impostazione predefinita, non è presente alcuna politica di restart; pertanto, se il demone Docker viene arrestato e successivamente riavviato, il container non riprenderà automaticamente l'esecuzione.

Le politiche di riavvio disponibili sono:

- `on-failure`: questa opzione indica che il container verrà riavviato automaticamente solo se termina con un errore
- `always`: se questa politica è impostata, il container verrà riavviato indipendentemente dal motivo per cui è terminato, a meno che non venga arrestato manualmente. In questo caso, il container riprenderà l'esecuzione automaticamente al successivo riavvio del demone Docker, magari seguito del riavvio del sistema
- `unless-stopped`: questa opzione mantiene l'ultimo stato del container. Se il container è stato arrestato manualmente, non verrà riavviato, anche dopo un riavvio del demone. Tuttavia, se il container era in esecuzione prima dell'arresto del demone, riprenderà automaticamente l'esecuzione

Le politiche di riavvio possono essere configurate sia tramite la riga di comando, utilizzando l'opzione `--restart`, ad esempio `docker run --restart always redis`, sia nel file `docker-compose.yml` attraverso l'apposita direttiva di configurazione `restart`.
