> ## Content Index
> Fetch the complete content index at: https://blog.craftbytes.it/llms.txt
> Use this file to discover other available public pages before exploring further.

# Docker in produzione per sysadmin: guida pratica senza fronzoli
- URL: https://blog.craftbytes.it/docker-in-produzione-per-sysadmin/
- Published: 2026-07-19T09:36:06.000Z
- Updated: 2026-07-19T09:36:06.000Z
- Description: Docker non è solo roba da developer. Per un sysadmin Linux è uno degli strumenti più pratici in produzione: meno VM, meno dipendenze, deploy ripetibili. Guida pratica senza teoria inutile.
- Author: Emanuele
- Tags: docker, linux, sysadmin, devops, container, produzione

Se sei un sysadmin e hai resistito a Docker finora, capisco la diffidenza. Docker nasce con un'aura "dev-friendly" che a volte fa sembrare lo strumento adatto solo per chi scrive codice. In realtà è uno degli strumenti più utili che puoi aggiungere al tuo arsenale operativo, specialmente se gestisci server Linux in ambienti PMI o MSP.

Questa guida è scritta per chi conosce Linux, sa usare il terminale, e vuole capire come portare Docker in produzione senza perdere il controllo di quello che gira sui propri server.

---

## Installazione su Linux (senza Docker Desktop)

Docker Desktop non serve su Linux. Serve sul Mac o Windows quando non hai accesso diretto al kernel Linux. Su un server Ubuntu o Debian, installi direttamente il demone:

```bash
# Ubuntu 22.04 / 24.04
curl -fsSL https://get.docker.com | sh

# Aggiungi il tuo utente al gruppo docker (eviti sudo ogni volta)
sudo usermod -aG docker $USER
newgrp docker

# Verifica
docker version
```

Lo script ufficiale di Docker è quello che si usa in produzione. Non usare il pacchetto `docker.io` dai repo Ubuntu: è vecchio e mancano le ultime feature.

---

## I quattro concetti che devi capire (e solo questi)

Docker ha una terminologia che all'inizio sembra più complicata di quello che è. Ti servono solo quattro concetti:

- **Image**: il blueprint del container, read-only. Come un template VM, ma leggero.
- **Container**: istanza in esecuzione di un'image. Puoi averne cento dalla stessa image.
- **Volume**: dove metti i dati persistenti. Tutto il resto del container è effimero.
- **Network**: come i container parlano tra loro (e con l'esterno).

Tutto il resto, registry, layer, overlay filesystem, viene da sé una volta che hai questi chiari.

---

## Docker Compose: lo strumento reale per la produzione

Nessuno gestisce container in produzione con comandi `docker run` lanciati a mano. Lo strumento che usi ogni giorno si chiama **Docker Compose**, ed è incluso in Docker moderno (`docker compose`, senza trattino).

Un file `compose.yml` descrive tutto ciò che serve per far girare un'applicazione:

```yaml
services:
  app:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  db:
    image: postgres:16
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  postgres_data:
```

Con questo file, avvii tutto con `docker compose up -d` e spegni tutto con `docker compose down`. Semplice da versionare su Git, semplice da replicare su un altro server.

---

## Restart policy: fondamentale, spesso ignorata

Se un container crasha e non hai configurato la restart policy, rimane giù finché non lo riavvii a mano. In produzione questo non è accettabile.

Le opzioni che usi in pratica:

- `restart: unless-stopped` riavvia sempre, tranne se l'hai fermato tu esplicitamente con `docker stop`. **Quello che vuoi in produzione.**
- `restart: always` riavvia sempre, anche dopo un `docker stop`. Utile se vuoi che riparta al boot automaticamente.
- `restart: on-failure` riavvia solo se esce con codice di errore. Per job e cron container.
- `restart: no` non riavvia mai. Default. Non usarlo in produzione.

---

## Logging: non riempire il disco

Il problema più comune sui server Docker in produzione è il disco che si riempie di log. Per default Docker accumula i log JSON senza limiti. Soluzione: configurare il log driver globalmente.

Modifica `/etc/docker/daemon.json`:

```json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
```

Poi ricarica Docker:

```bash
sudo systemctl reload docker
```

I nuovi container useranno questi limiti automaticamente. I container esistenti vanno ricreati per applicare la modifica.

Se hai già uno stack di log centralizzato (Loki, ELK), puoi usare i driver `loki` o `gelf` argomento per un articolo dedicato.

---

## Volumi: dove finiscono i tuoi dati

Regola fondamentale: **tutto ciò che deve sopravvivere al container va su un volume**. I container sono usa e getta, l'image si aggiorna, il container si ricrea, i dati restano sul volume.

Due modi per montare dati:

```yaml
# Bind mount: mappa una cartella dell'host nel container
volumes:
  - /opt/myapp/config:/app/config

# Named volume: gestito da Docker, preferibile per database
volumes:
  - postgres_data:/var/lib/postgresql/data
```

Per i database usa sempre named volume. Per file di configurazione che vuoi versionare su Git, il bind mount va bene.

Backup di un named volume:

```bash
docker run --rm \
  -v postgres_data:/data \
  -v $(pwd):/backup \
  alpine \
  tar czf /backup/postgres_backup_$(date +%Y%m%d).tar.gz -C /data .
```

---

## Sicurezza base: quello che non puoi ignorare

Docker di default è troppo permissivo per la produzione. Tre regole da applicare sempre:

**1\. Non girare come root dentro il container**

```dockerfile
FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
```

**2\. Mai `--privileged` senza una ragione precisa**  
`--privileged` dà al container accesso completo all'host. Se un container compromesso gira con questo flag, l'attaccante ha root sul server.

**3\. Filesystem read-only dove possibile**

```yaml
services:
  app:
    image: myapp:latest
    read_only: true
    tmpfs:
      - /tmp
    volumes:
      - app_data:/app/data
```

---

## Comandi essenziali per il troubleshooting

```bash
# Tutti i container (anche quelli fermi)
docker ps -a

# Log in real-time
docker logs -f nome_container

# Shell dentro il container per debug
docker exec -it nome_container sh

# Uso risorse in real-time (come top, ma per container)
docker stats

# Configurazione completa del container
docker inspect nome_container

# Quanto spazio occupa Docker
docker system df

# Pulizia: immagini, container fermi, volumi orfani
# ATTENZIONE: rimuove anche i volumi non montati
docker system prune -a --volumes
```

---

## Pattern da non dimenticare in produzione

- **Un servizio per container** non mettere nginx + app + database nello stesso container. Rompe scaling e aggiornamento indipendente.
- **Tag specifici, mai `latest`** `postgres:latest` è una bomba a orologeria. Usa `postgres:16.3` e aggiorna con controllo.
- **Segreti fuori dal Compose file** usa `.env` file escluso da Git, o Docker Secrets in ambienti multi-nodo.
- **Health check sempre definito**:

```yaml
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost/health"]
  interval: 30s
  timeout: 10s
  retries: 3
  start_period: 40s
```

Senza health check, Docker considera il container "up" non appena il processo parte, anche se l'applicazione ci mette 30 secondi ad inizializzarsi o è in crash loop.

---

## Conclusione

Docker in produzione non è complicato se parti dai concetti giusti: Compose per orchestrare, volumi per i dati, restart policy sempre configurata, logging con limiti, sicurezza minima ma presente.

Non serve Kubernetes per la maggior parte dei workload di una PMI o di un MSP. Docker Compose su un server Linux ben configurato copre il 90% dei casi d'uso, con molta meno complessità operativa.

Nel prossimo articolo vedremo come monitorare i container Docker con [Zabbix](https://blog.craftbytes.it/zabbix-nel-2026-perche-lo-uso-ancora/): metriche, alert e LLD per scoprire automaticamente i container che girano sul server.