Pourquoi Docker Compose : Django + PostgreSQL ?
Contexte réel : pourquoi un dev a besoin de ca au quotidien
Au cours de la vie d'un développeur, il est fréquent de travailler sur plusieurs projets en même temps, chacun ayant ses propres dépendances et environnements de développement. Par exemple, vous pourriez être impliqué dans le développement d'une application Django qui nécessite une base de données PostgreSQL. Gérer chaque projet avec son propre serveur, son propre interpréteur Python et sa propre configuration peut être fastidieux et coûteux en termes de ressources.
Un cas d'usage concret en 2-3 phrases
Imaginez que vous travaillez sur un projet Django pour une petite entreprise. L'entreprise a besoin d'une base de données PostgreSQL pour stocker les informations des clients, les commandes et les articles. En utilisant Docker Compose, vous pouvez configurer facilement un environnement de développement local qui comprend le serveur Web Gunicorn, la base de données PostgreSQL et même le service d'administration Django admin.
Prerequis
Connaissances nécessaires :
- Base en Python
- Connaissance de Django
- Familiarité avec les bases de données SQL et PostgreSQL
- Compréhension des concepts de Docker (images, conteneurs)
Outils à installer :
- Docker : version stable
- Docker Compose : version latest
- Un éditeur de code (par exemple, VSCode, PyCharm)
Concepts fondamentaux
1. Dockerfile :
Un fichier Dockerfile contient des instructions pour construire une image Docker.
## Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "manage.py", "runserver"]
2. docker-compose.yml :
Ce fichier définit et configure les services, réseaux et volumes Docker.
## docker-compose.yml
version: '3.9'
services:
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app
ports:
- "8000:8000"
depends_on:
- db
db:
image: postgres:13
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
3. Volumes :
Les volumes sont des répertoires spéciaux qui stockent les données de manière persistante, indépendamment des conteneurs qui les utilisent.
## bash
docker-compose up -d
Mise en pratique : projet fil rouge
Étape 1 : Initialisation du projet Django
## bash
django-admin startproject myproject .
Étape 2 : Configuration de la base de données PostgreSQL
Ouvrez myproject/settings.py et modifiez les configurations pour utiliser PostgreSQL :
## myproject/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.getenv('POSTGRES_DB', 'mydatabase'),
'USER': os.getenv('POSTGRES_USER', 'user'),
'PASSWORD': os.getenv('POSTGRES_PASSWORD', 'password'),
'HOST': 'db',
'PORT': 5432,
}
}
Étape 3 : Création d'un modèle
Créez un nouveau fichier models.py dans le répertoire de l'application (par exemple, myapp/models.py) :
## myapp/models.py
from django.db import models
class Task(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
completed = models.BooleanField(default=False)
def __str__(self):
return self.title
Étape 4 : Migrations
Créez et appliquez les migrations pour créer la table dans la base de données :
## bash
python manage.py makemigrations
python manage.py migrate
Étape 5 : Création d'une vue
Créez un fichier views.py dans le répertoire de l'application (par exemple, myapp/views.py) :
## myapp/views.py
from django.shortcuts import render
from .models import Task
def task_list(request):
tasks = Task.objects.all()
return render(request, 'task_list.html', {'tasks': tasks})
Étape 6 : Création d'un template HTML
Créez un répertoire templates et un fichier task_list.html dans le répertoire de l'application (par exemple, myapp/templates/task_list.html) :
<!-- myapp/templates/task_list.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Task List</title>
</head>
<body>
<h1>Task List</h1>
<ul>
{% for task in tasks %}
<li>task.title - task.description</li>
{% endfor %}
</ul>
</body>
</html>
Étape 7 : Configuration de l'URL
Ajoutez une URL pour la vue dans myapp/urls.py :
## myapp/urls.py
from django.urls import path
from .views import task_list
urlpatterns = [
path('', task_list, name='task_list'),
]
Étape 8 : Ajout de l'application au projet
Ajoutez myapp à la liste des applications dans myproject/settings.py :
## myproject/settings.py
INSTALLED_APPS = [
...
'myapp',
]
Étape 9 : Lancement du projet avec Docker Compose
## bash
docker-compose up -d
Allez sur http://localhost:8000/ pour voir votre application en action.
Erreurs frequentes et debugging
Erreur 1 : Impossible de se connecter à la base de données
Code incorrect
## myproject/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'user',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': 5432,
}
}
Code correct
## myproject/settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.getenv('POSTGRES_DB', 'mydatabase'),
'USER': os.getenv('POSTGRES_USER', 'user'),
'PASSWORD': os.getenv('POSTGRES_PASSWORD', 'password'),
'HOST': 'db',
'PORT': 5432,
}
}
Erreur 2 : Migrations non appliquées
Code incorrect
## bash
python manage.py migrate
Code correct
## bash
docker-compose exec web python manage.py migrate
Erreur 3 : L'application ne démarre pas
Code incorrect
## bash
docker-compose up
Code correct
## bash
docker-compose up -d
Pour aller plus loin
Utiliser Docker Secrets pour gérer les mots de passe sensibles Docker Secrets
Optimisation des images Docker avec Multi-stage builds Multi-stage builds
Utiliser Docker Compose pour développer en production Docker Compose for Production
Défi pratique :
Implémentez une API RESTful avec Django et DRF (Django Rest Framework) pour permettre la création, la lecture, la mise à jour et la suppression de tâches. Assurez-vous que l'API est sécurisée avec des tokens JWT.