Premessa
Questo tutorial mira a guidare uno sviluppatore principiante nella configurazione di un ambiente di sviluppo Django containerizzato, partendo dall'installazione iniziale fino alla configurazione completa.
Prerequisiti di Sistema
1. Installazioni Preliminari
Prima di iniziare, assicurati di aver installato i seguenti strumenti:
Per Ubuntu/Debian:
# Aggiornamenti di sistema
sudo apt update && sudo apt upgrade -y
# Installazioni essenziali
sudo apt install -y \
git \
curl \
wget \
software-properties-common \
apt-transport-https \
ca-certificates \
gnupg \
lsb-release \
postgresql-client \
python3-pip \
python3-venv \
build-essential \
libpq-dev
Per altre distribuzioni Linux, adatta i comandi:
- Fedora/CentOS:
dnf
oyum
- Arch Linux:
pacman
2. Installazione di Docker
# Installazione di Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker compose-plugin
# Aggiungi il tuo utente al gruppo docker
sudo usermod -aG docker $USER
# Riavvia per applicare le modifiche
sudo systemctl restart docker
3. Verifiche
# Verifica delle installazioni
docker --version
docker compose --version
python3 --version
psql --version
Struttura del Progetto Django Dockerizzato
Creazione della Struttura del Progetto
# Creare la directory del progetto
mkdir progetto_django_docker
cd progetto_django_docker
# Struttura delle directory
mkdir -p app/mio_progetto
touch app/Dockerfile
touch app/requirements.txt
touch app/entrypoint.sh
touch docker compose.yml
touch .env
1. File requirements.txt
# app/requirements.txt
Django==4.2.7
psycopg2-binary==2.9.9
gunicorn==21.2.0
python-dotenv==1.0.0
2. Dockerfile
# app/Dockerfile
FROM python:3.11-slim
# Metadati
LABEL maintainer="Tuo Nome <tua.email@esempio.com>"
# Variabili d'ambiente
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PYTHONPATH=/app
# Directory di lavoro
WORKDIR /app
# Installare le dipendenze di sistema
RUN apt-get update && apt-get install -y \
postgresql-client \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# Copiare e installare i requirements
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copiare il resto del progetto
COPY . .
# Dare i permessi allo script di entrypoint
RUN chmod +x /app/entrypoint.sh
# Punto di ingresso
ENTRYPOINT ["/app/entrypoint.sh"]
Script entrypoint.sh: Comprendere l'Attesa del Database
Perché Attendere il Database?
#!/bin/bash
# Attesa della disponibilità del database
echo "In attesa del database..."
while ! nc -z db 5432; do
sleep 1
done
echo "Database pronto!"
Contesto Tecnico
All'avvio di un'applicazione containerizzata, non tutti i servizi partono istantaneamente. Il database PostgreSQL può richiedere alcuni secondi per essere completamente operativo.
Problematica Concreta
Se la tua applicazione Django tenta di connettersi al database prima che sia pronto, incontrerai un errore di connessione. Questo potrebbe bloccare l'avvio completo della tua applicazione.
Come Funziona?
nc -z db 5432
: Verifica se la porta 5432 (porta PostgreSQL) è accessibilewhile
: Ciclo fino a quando la connessione è possibilesleep 1
: Pausa di un secondo tra ogni tentativo
Codice Completo con Migrazioni
#!/bin/bash
# Attesa del database
echo "In attesa del database..."
while ! nc -z db 5432; do
sleep 1
done
echo "Database pronto!"
# Applicare le migrazioni Django
python manage.py migrate
# Avviare il server web
exec gunicorn --bind 0.0.0.0:8000 mio_progetto.wsgi:application
Docker Compose: Comprendere la Configurazione
Struttura del File docker compose.yml
version: '3.8' # Versione della sintassi Docker Compose
services:
# Servizio Web (Applicazione Django)
web:
build:
context: ./app
dockerfile: Dockerfile
volumes:
- ./app:/app # Sincronizzazione del codice sorgente
ports:
- "8000:8000" # Mappatura delle porte
env_file:
- .env # File di ambiente
depends_on:
- db # Dipendenza dal servizio database
networks:
- dev_network # Rete personalizzata
# Servizio Database
db:
image: postgres:15-alpine
volumes:
- postgres_data:/var/lib/postgresql/data # Persistenza dei dati
environment:
- POSTGRES_DB=progetto_db
- POSTGRES_USER=progetto_user
- POSTGRES_PASSWORD=password_segreta
ports:
- "5432:5432" # Esposizione della porta PostgreSQL
networks:
- dev_network
# Volumi e Reti
volumes:
postgres_data: # Volume per i dati PostgreSQL
networks:
dev_network:
driver: bridge # Tipo di rete
Spiegazioni Dettagliate
1. Reti (Networks)
dev_network
: Una rete personalizzata che permette la comunicazione tra containerdriver: bridge
: Crea una rete isolata sull'host
2. Porte: Interna vs Esterna
- Formato:
"8000:8000"
- Prima porta: Porta esterna (accessibile dall'host)
- Seconda porta: Porta interna del container
3. Dipendenze tra Servizi
depends_on: - db
significa che il servizio web si avvierà dopo il servizio database- Garantisce un ordine di avvio, non una garanzia di "pronto all'uso"
Accesso al Terminale dei Container
# Accedere al terminale di un servizio specifico
docker compose exec web bash
docker compose exec db bash
Punti Importanti
- Funziona SOLO quando i container sono in esecuzione
- Permette di effettuare azioni direttamente nel container
- Equivalente a un accesso SSH per i container
Consigli Aggiuntivi
- Le versioni recenti di Docker rilevano automaticamente la versione di Compose
- Specificare sempre un contesto e un Dockerfile per maggiore chiarezza
- Utilizzare variabili d'ambiente per configurazioni sensibili
Comandi Utili
# Avviare i servizi
docker compose up
# Avviare in modalità distaccata
docker compose up -d
# Fermare i servizi
docker compose down
# Vedere i log
docker compose logs
# Eseguire un comando in un servizio
docker compose run web python manage.py createsuperuser
Perché Questi Dettagli Sono Importanti?
- Comprensione approfondita dei meccanismi
- Debug più efficiente
- Configurazione più flessibile
- Migliore padronanza dell'ambiente di sviluppo
File .env
# Configurazione Django
DEBUG=1
SECRET_KEY=la_tua_chiave_segreta_ultra_sicura
DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1
# Configurazione Database
DB_NAME=progetto_db
DB_USER=progetto_user
DB_PASSWORD=password_segreta
DB_HOST=db
DB_PORT=5432
Creazione del Progetto Django
Inizializzazione del Progetto
# Creare e inizializzare il progetto Django
docker compose run --rm web django-admin startproject mio_progetto .
# Configurare settings.py per il database
# Modificare la sezione DATABASES:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.getenv('DB_NAME', 'progetto_db'),
'USER': os.getenv('DB_USER', 'progetto_user'),
'PASSWORD': os.getenv('DB_PASSWORD', 'password_segreta'),
'HOST': os.getenv('DB_HOST', 'db'),
'PORT': os.getenv('DB_PORT', '5432'),
}
}
Avvio e Utilizzo
Comandi Essenziali
# Costruire e avviare i container
docker compose up --build
# Fermare i container
docker compose down
# Creare una nuova applicazione
docker compose run --rm web python manage.py startapp mia_nuova_app
# Creare migrazioni
docker compose run --rm web python manage.py makemigrations
# Applicare le migrazioni
docker compose run --rm web python manage.py migrate
Consigli e Buone Pratiche
- Sicurezza:
- Non committare mai il file
.env
- Utilizzare un
.env.example
con valori fittizi - Generare chiavi segrete robuste
- Non committare mai il file
- Prestazioni:
- Utilizzare volumi per lo sviluppo
- Ottimizzare le immagini Docker
- Gestire le dipendenze con cautela
- Sviluppo:
- Utilizzare
docker compose.override.yml
per configurazioni specifiche - Impostare un workflow git adatto
- Utilizzare
Risoluzione dei Problemi
- Verificare i log:
docker compose logs
- Verificare lo stato dei container:
docker compose ps
- Connessione a un container:
docker compose exec web bash
Evoluzioni Possibili
- Aggiungere un container per Redis/Celery
- Configurare un proxy Nginx
- Configurare un volume per i file statici