MariaDB in Docker: Deploy e Best Practices
MariaDB rappresenta una delle soluzioni database più affidabili e performanti nel panorama open source. Quando combinato con Docker, offre agli sviluppatori e ai team DevOps un ambiente di sviluppo e produzione estremamente flessibile e scalabile. In questa guida completa, esploreremo come deployare MariaDB utilizzando Docker, implementando le migliori pratiche per sicurezza, performance e gestione dei dati.
Introduzione a MariaDB e Docker
MariaDB è un fork di MySQL sviluppato dalla comunità open source, nato dalla necessità di mantenere un database management system completamente libero e compatibile con MySQL. Docker, d'altra parte, ha rivoluzionato il modo in cui deployamo e gestiamo le applicazioni, fornendo containerizzazione leggera e portabilità cross-platform.
L'utilizzo di MariaDB in container Docker offre numerosi vantaggi:
- Isolamento: Ogni istanza MariaDB funziona in un ambiente isolato
- Portabilità: Il database può essere spostato facilmente tra ambienti diversi
- Scalabilità: Possibilità di creare rapidamente nuove istanze
- Gestione delle versioni: Controllo preciso sulla versione di MariaDB utilizzata
- Backup e restore semplificati: Gestione dei dati tramite volumi Docker
Prerequisiti e Setup Iniziale
Prima di iniziare con il deploy di MariaDB in Docker, assicuriamoci di avere tutti i prerequisiti necessari:
Requisiti di Sistema
- Docker Engine 20.10+ installato e configurato
- Docker Compose 2.0+ (opzionale ma raccomandato)
- Almeno 2GB di RAM disponibili
- Spazio disco sufficiente per i dati del database
Verifica dell'Installazione Docker
Verifichiamo che Docker sia correttamente installato e funzionante:
docker --version
docker run hello-world
Questi comandi dovrebbero restituire la versione di Docker installata e confermare che il sistema è operativo.
Deploy Base di MariaDB con Docker
Primo Container MariaDB
Iniziamo con un deploy base di MariaDB utilizzando il comando Docker run:
docker run --name mariadb-container \
-e MYSQL_ROOT_PASSWORD=your_secure_password \
-e MYSQL_DATABASE=myapp_db \
-e MYSQL_USER=myapp_user \
-e MYSQL_PASSWORD=user_password \
-p 3306:3306 \
-d mariadb:10.9
Analizziamo i parametri utilizzati:
--name mariadb-container: Assegna un nome specifico al container-e MYSQL_ROOT_PASSWORD: Imposta la password per l'utente root-e MYSQL_DATABASE: Crea automaticamente un database all'avvio-e MYSQL_USER/MYSQL_PASSWORD: Crea un utente non-root con relativa password-p 3306:3306: Mappa la porta del container sulla porta dell'host-d: Esegue il container in background (detached mode)
Verifica del Container
Verifichiamo che il container sia attivo e funzionante:
docker ps
docker logs mariadb-container
Per connetterci al database dal container stesso:
docker exec -it mariadb-container mysql -u root -p
Gestione dei Dati con Volumi Docker
Persistenza dei Dati
Uno degli aspetti più critici quando si lavora con database in container è la persistenza dei dati. Per default, i dati di MariaDB vengono memorizzati all'interno del container e vengono persi quando il container viene rimosso. Per risolvere questo problema, utilizziamo i volumi Docker:
docker volume create mariadb_data
docker run --name mariadb-persistent \
-e MYSQL_ROOT_PASSWORD=your_secure_password \
-e MYSQL_DATABASE=myapp_db \
-v mariadb_data:/var/lib/mysql \
-p 3306:3306 \
-d mariadb:10.9
Volumi Named vs Bind Mounts
Docker offre diverse opzioni per la gestione dei volumi:
| Tipo | Sintassi | Pro | Contro |
|---|---|---|---|
| Named Volume | -v volume_name:/var/lib/mysql | Gestito da Docker, backup semplificato | Meno controllo sulla posizione |
| Bind Mount | -v /host/path:/var/lib/mysql | Controllo completo del percorso | Dipendenza dal filesystem host |
Utilizzo di Docker Compose per MariaDB
Docker Compose semplifica notevolmente la gestione di container complessi. Creiamo un file docker-compose.yml per il nostro setup MariaDB:
version: '3.8'
services:
mariadb:
image: mariadb:10.9
container_name: mariadb-app
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
ports:
- "3306:3306"
volumes:
- mariadb_data:/var/lib/mysql
- ./config/mariadb.cnf:/etc/mysql/conf.d/custom.cnf:ro
- ./init:/docker-entrypoint-initdb.d:ro
networks:
- app_network
volumes:
mariadb_data:
driver: local
networks:
app_network:
driver: bridge
File di Configurazione Ambiente
Creiamo un file .env per gestire le variabili di ambiente in modo sicuro:
MYSQL_ROOT_PASSWORD=your_very_secure_root_password
MYSQL_DATABASE=production_db
MYSQL_USER=app_user
MYSQL_PASSWORD=app_user_secure_password
Per avviare lo stack:
docker-compose up -d
Configurazione Avanzata di MariaDB
File di Configurazione Personalizzato
MariaDB può essere configurato tramite file di configurazione personalizzati. Creiamo un file config/mariadb.cnf:
[mysqld]
# Configurazioni di base
max_connections = 200
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
# Ottimizzazioni per performance
query_cache_type = 1
query_cache_size = 128M
tmp_table_size = 64M
max_heap_table_size = 64M
# Configurazioni di sicurezza
bind-address = 0.0.0.0
skip-name-resolve
# Logging
log_error = /var/log/mysql/error.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
# Character set
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
Script di Inizializzazione
Possiamo automatizzare la creazione di tabelle e dati iniziali tramite script SQL nella directory init/:
-- init/01-schema.sql
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_email ON users(email);
Sicurezza e Best Practices
Gestione delle Password e Secrets
La sicurezza è fondamentale quando si gestiscono database in produzione. Ecco alcune best practices essenziali:
- Mai hardcodare password: Utilizzare sempre variabili di ambiente o Docker secrets
- Password complesse: Implementare policy di password robuste
- Principio del least privilege: Creare utenti specifici con permessi minimi necessari
- Network isolation: Utilizzare reti Docker personalizzate
Implementazione Docker Secrets
Per ambienti più sicuri, utilizziamo Docker Secrets con Docker Swarm:
version: '3.8'
services:
mariadb:
image: mariadb:10.9
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root_password
MYSQL_DATABASE: production_db
secrets:
- mysql_root_password
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
volumes:
- mariadb_data:/var/lib/mysql
networks:
- backend
secrets:
mysql_root_password:
file: ./secrets/mysql_root_password.txt
volumes:
mariadb_data:
networks:
backend:
driver: overlay
Configurazione Firewall e Networking
Limitiamo l'accesso al database attraverso configurazioni di rete appropriate:
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # Rete interna non accessibile dall'esterno
Monitoraggio e Logging
Configurazione dei Log
Un sistema di logging efficace è cruciale per il debugging e il monitoraggio. Configuriamo Docker per gestire i log di MariaDB:
services:
mariadb:
image: mariadb:10.9
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
- ./logs:/var/log/mysql
Health Checks
Implementiamo health checks per monitorare lo stato del database:
services:
mariadb:
image: mariadb:10.9
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Backup e Restore Strategies
Backup Automatizzati
Implementiamo una strategia di backup utilizzando un container dedicato:
services:
mariadb-backup:
image: mariadb:10.9
depends_on:
- mariadb
environment:
MYSQL_HOST: mariadb
MYSQL_USER: root
MYSQL_PASSWORD: ${MYSQL_ROOT_PASSWORD}
volumes:
- ./backups:/backups
- ./scripts/backup.sh:/backup.sh:ro
command: >
sh -c "chmod +x /backup.sh &&
echo '0 2 * * * /backup.sh' | crontab - &&
crond -f"
Script di Backup
Creiamo uno script di backup completo:
#!/bin/bash
# scripts/backup.sh
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)
DATABASES=$(mysql -h${MYSQL_HOST} -u${MYSQL_USER} -p${MYSQL_PASSWORD} -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql|sys)")
mkdir -p ${BACKUP_DIR}/${DATE}
for db in $DATABASES; do
echo "Backing up database: $db"
mysqldump -h${MYSQL_HOST} -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
--single-transaction \
--routines \
--triggers \
--add-drop-database \
--databases $db > ${BACKUP_DIR}/${DATE}/${db}.sql
done
# Compressione dei backup
cd ${BACKUP_DIR}
tar -czf ${DATE}.tar.gz ${DATE}/
rm -rf ${DATE}/
# Pulizia backup vecchi (mantieni ultimi 7 giorni)
find ${BACKUP_DIR} -name "*.tar.gz" -mtime +7 -delete
echo "Backup completed: ${DATE}.tar.gz"
Ottimizzazione delle Performance
Configurazione Memoria e CPU
Ottimizzi