← Retour aux projets

Mise en production portfolio

Déploiement et sécurisation d'une application Django sur un VPS avec Docker, PostgreSQL, reverse proxy et HTTPS.

Docker SQL HTTPS Linux

Mise en production d'un portfolio Django sur un VPS OVH

1. Présentation du projet

L'objectif de ce projet était de déployer mon portfolio personnel de cybersécurité, développé avec Django, afin de le rendre accessible publiquement en HTTPS.

Le projet m'a permis de mettre en pratique plusieurs aspects de l'administration système et du déploiement d'applications web : conteneurisation, gestion d'une base de données, configuration DNS, reverse proxy, certificats TLS et préparation de Django pour la production.

Stack technique

  • Python / Django : application web
  • Gunicorn : serveur WSGI
  • PostgreSQL : base de données
  • Docker / Docker Compose : conteneurisation
  • Nginx Proxy Manager : reverse proxy et gestion du HTTPS
  • WhiteNoise : distribution des fichiers statiques
  • Let's Encrypt : certificats TLS
  • OVH : nom de domaine et VPS
  • Git / GitHub : versionnement et déploiement

2. Préparation de Django pour la production

La première étape a consisté à séparer les paramètres de production du code source grâce aux variables d'environnement.

Les principaux paramètres concernent notamment le mode debug, les domaines autorisés et les origines approuvées pour la protection CSRF.

DEBUG = os.environ.get('DJANGO_DEBUG', 'False').lower() == 'true'

En production, DEBUG=False permet d'éviter l'exposition d'informations de diagnostic sensibles. Les paramètres propres à l'environnement sont conservés dans un fichier .env, qui ne doit pas être versionné dans Git.

3. Conteneurisation et base de données

L'application a été déployée avec Docker Compose, en séparant Django et PostgreSQL dans des conteneurs distincts.

  • web : Django exécuté avec Gunicorn.
  • db : PostgreSQL, accessible uniquement via le réseau Docker interne.

Un volume Docker assure la persistance des données PostgreSQL. Les migrations Django ont ensuite été appliquées pour créer la structure de la base de données de production.

Cette étape m'a également permis de distinguer les migrations de schéma du transfert des données : créer les tables ne suffit pas à récupérer automatiquement le contenu de la base locale.

4. Configuration des fichiers statiques

Lors des premiers tests, le site était accessible, mais le CSS ne se chargeait pas correctement. Le problème venait de la configuration des fichiers statiques en production.

J'ai configuré WhiteNoise et la commande collectstatic pour rassembler les ressources nécessaires à leur distribution.

python manage.py collectstatic --noinput

Les fichiers sources présents dans static/ sont ainsi collectés dans staticfiles/. WhiteNoise permet ensuite de servir les ressources statiques, comme les feuilles CSS et les fichiers JavaScript, sans devoir exposer directement le serveur de développement Django.

Après vérification des réponses HTTP, le style du site était correctement chargé.

5. Configuration DNS et reverse proxy

Le domaine jeremycorazza.com a été configuré chez OVH pour pointer vers l'adresse IP publique du VPS au moyen d'enregistrements DNS de type A, pour le domaine principal et le sous-domaine www.

J'ai ensuite utilisé Nginx Proxy Manager comme reverse proxy. Il reçoit les requêtes provenant d'Internet et les transmet au service Django sur le réseau Docker partagé.

Visiteur
   |
   v
DNS OVH
   |
   v
VPS OVH : ports 80 / 443
   |
   v
Nginx Proxy Manager
   |
   v
Réseau Docker "proxy"
   |
   v
Django / Gunicorn : web:8000
   |
   v
PostgreSQL : db:5432

Le port 8000 de Django n'est pas directement publié sur Internet. La communication entre les services s'effectue via le réseau Docker.

6. Migration des données du portfolio

Après le déploiement, le site fonctionnait, mais les projets présents dans l'environnement local n'étaient pas encore disponibles dans la base de production.

J'ai utilisé les outils intégrés à Django pour exporter et importer les données de l'application portfolio.

Export local :

python manage.py dumpdata portfolio \
  --natural-foreign \
  --natural-primary \
  --indent 2 \
  --output portfolio_data.json

Import en production :

python manage.py loaddata /app/portfolio_data.json

L'export était volontairement limité à l'application portfolio, afin de ne pas transférer les comptes utilisateurs Django. Après l'import, les projets, catégories et tags étaient disponibles sur le site de production.

7. Mise en place du HTTPS

J'ai configuré un certificat Let's Encrypt directement dans Nginx Proxy Manager.

La configuration permet : - d'activer HTTPS sur le domaine ; - de rediriger les requêtes HTTP vers HTTPS ; - de gérer automatiquement le renouvellement du certificat.

Le certificat et le reverse proxy sont ainsi gérés à un seul endroit, sans devoir exposer directement Gunicorn.

8. Gestion des images uploadées

Les fichiers statiques et les fichiers téléversés par l'administration Django ne sont pas identiques.

  • Les fichiers statiques, comme le CSS, sont collectés par collectstatic et servis par WhiteNoise.
  • Les médias uploadés, comme les images illustrant les articles, nécessitent un stockage persistant et une distribution adaptée à la production.

Pour les médias, j'ai mis en place un volume Docker dédié et un service Nginx en lecture seule pour distribuer les fichiers. Nginx Proxy Manager transmet les requêtes /media/ à ce service.

Cette séparation permet de conserver les images lors de la reconstruction du conteneur Django, tout en évitant d'activer DEBUG=True en production.

9. Résultat et compétences acquises

Le portfolio est désormais accessible publiquement en HTTPS. L'application Django, la base PostgreSQL, les fichiers statiques et les médias sont gérés par des services distincts.

Ce projet m'a permis de pratiquer :

  • le déploiement d'une application Django en production ;
  • la conteneurisation et les réseaux Docker ;
  • la configuration PostgreSQL et la migration des données ;
  • la gestion des variables d'environnement ;
  • le diagnostic des problèmes de DNS et de fichiers statiques ;
  • la configuration d'un reverse proxy et de certificats TLS ;
  • la persistance des données et des médias ;
  • l'utilisation de Git et GitHub dans un processus de déploiement.

Au-delà du développement web, cette mise en production m'a permis de mieux comprendre les interactions entre une application, son serveur, sa base de données, son réseau et les mécanismes qui rendent un service accessible de manière sécurisée sur Internet.