# Docker file

## Introduzione

Il `Dockerfile` è un file di testo che contiene una serie di istruzioni per creare immagini Docker personalizzate. Nel caso di Podman, il file è denominato `Containerfile`, ma la sintassi rimane invariata.

```dockerfile
FROM ubuntu

LABEL Description="ubuntu con curl preinstallato"
RUN apt update && apt install -y curl

ENTRYPOINT ["/usr/bin/curl"]
```

In questo esempio, l'istruzione `FROM` specifica l'immagine base, `LABEL` imposta una descrizione e `RUN` esegue i comandi `apt update` e `apt install -y curl`.

Ogni istruzione nel Dockerfile crea un nuovo layer. Se si utilizzano molte istruzioni, l'immagine risultante sarà più grande. Per ridurre le dimensioni dell'immagine, è consigliabile combinare più comandi in un'unica istruzione. Ad esempio, l'uso di apt-get update e apt-get install in un'unica riga evita la creazione di layer aggiuntivi.

Durante la creazione dell'immagine, il container viene spento e riacceso tra un'istruzione e l'altra. Questo significa che non c'è continuità tra le istruzioni: le variabili d'ambiente impostate in un'istruzione non saranno disponibili nelle istruzioni successive.

### Caching

Docker utilizza un meccanismo di caching per ottimizzare la creazione delle immagini. Se un'istruzione non viene modificata, Docker utilizzerà il risultato della cache invece di eseguire nuovamente l'istruzione. Tuttavia, se un'istruzione prevede il download di una risorsa, la versione memorizzata nella cache potrebbe non essere aggiornata se la risorsa online è cambiata. Per forzare Docker a non utilizzare la cache, è possibile utilizzare l'opzione `--no-cache` durante la costruzione dell'immagine.

### Direttive

Le direttive più comuni utilizzate in un Dockerfile includono:

- `ADD`: consente di aggiungere file o directory remoti o locali al container
- `COPY`: copia file e directory locali all'interno del container
- `ENV`: imposta variabili d'ambiente che saranno disponibili in fase di esecuzione del container
- `EXPOSE`: indica al demone Docker che il container ascolta su una certa porta
- `FROM`: definisce l'immagine di base da cui derivare la nuova immagine
- `RUN`: esegue comandi all'interno del container durante la costruzione dell'immagine
- `USER`: specifica l'utente con cui vengono eseguite le operazioni all'interno del container. Se non viene specificato alcun utente, le operazioni vengono eseguite con l'utente root. Questa direttiva imposta anche l'utente che eseguirà i processi all'interno del container una volta avviato
- `WORKDIR`: imposta la directory di lavoro all'interno del container. Ha una duplice funzione: sposta il contesto nella directory specificata e, se questa non esiste, la crea automaticamente
- `ENV`: consente di impostare variabili d'ambiente che saranno sempre disponibili all'interno del container
- `VOLUME`: rende persistente il percorso specificato utilizzando un volume anonimo
- `ENTRYPOINT`: definisce l'eseguibile predefinito all'avvio del container. Se non viene specificato, l'eseguibile predefinito è tipicamente `/bin/sh`
- `CMD`: specifica i parametri di avvio per l'ENTRYPOINT

```dockerfile
# Pull base image
FROM debian:latest

# Dockerfile Maintainer
MAINTAINER dado "dado@mail.me"

# Install nginx and adjust nginx config to stay in foreground
RUN apt-get update && apt-get install --no-install-recommends -y nginx; \
 echo "daemon off;" >> /etc/nginx/nginx.conf

# Expose HTTP
EXPOSE 80

# Start nginx
CMD ["/usr/sbin/nginx"]
```

## Buid di una immagine Docker

Per costruire un'immagine Docker, è necessario utilizzare il seguente comando:

```bash
docker build [--no-cache] -t <username>/image_name /path/to/dockerfile
```

Ad esempio, se il Dockerfile si trova nella cartella corrente, il comando sarà:

```bash
docker build -t <username>/myubuntu .
```

L'immagine viene costruita seguendo le istruzioni specificate nel Dockerfile. Eseguendo il comando `docker image ls`, sarà possibile visualizzare l'immagine appena costruita, che potrà essere eseguita come qualsiasi altra immagine Docker.

## Pubblicazione dell'immagine su un registry

È possibile caricare l'immagine su un registry, come Docker Hub, dove sarà pubblica per impostazione predefinita. Prima di procedere, è necessario effettuare il login:

```bash
docker login
```

Dopo aver effettuato il login, è possibile taggare l'immagine e caricarla utilizzando i seguenti comandi:

```bash
docker tag myubuntu <username>/myubuntu:<tag>
docker push <username>/myubuntu:latest
```

## Backup e ripristino dell'immagine

Per eseguire un backup dell'immagine localmente, senza caricarla su un registry, utilizzare il comando `docker save`:

```bash
docker save -o myubuntu.tar.gz myubuntu
```

Per importare l'immagine su un altro sistema, utilizzare il comando:

```bash
docker image import myubuntu.tar.gz <username>/myubuntu:latest
```
