Dockeriser une API Flask de zéro sur Ubuntu : le guide complet pour ingénieurs africains

Dockeriser une API Flask de zéro sur Ubuntu : le guide complet

Il y a un problème que tout développeur africain a vécu au moins une fois.

Tu construis une app. Elle tourne parfaitement sur ta machine. Tu l’envoies en production — ou à ton collègue, ou au client. Elle plante.

“Mais ça marchait chez moi…”

Docker est la solution définitive à ce problème. Dans ce guide, je te montre comment dockeriser une API Flask réelle, de bout en bout, sur Ubuntu — avec les bonnes pratiques de production dès le départ.

Ce qu’on va construire

À la fin de ce guide, tu auras :

  • Un projet Flask cloné depuis GitHub et analysé
  • Un Dockerfile optimisé avec gestion intelligente du cache
  • Une app servie par Gunicorn (le vrai serveur de prod, pas flask run)
  • Une configuration sécurisée par variables d’environnement
  • Une image versionnée et publiée sur Docker Hub

Prérequis

  • Ubuntu 22.04 ou 24.04
  • Docker installé (guide officiel)
  • Git installé
  • Connaissances de base en Python et ligne de commande

Étape 1 — Installer Docker sur Ubuntu

Sur Ubuntu, Docker s’installe nativement — pas besoin de virtualisation comme sur Windows.

# Supprime les anciennes versions si présentes
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do
    sudo apt-get remove $pkg
done

# Installe Docker via le script officiel
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Autorise ton utilisateur à utiliser Docker sans sudo
sudo usermod -aG docker $USER
newgrp docker

# Vérifie l'installation
docker run hello-world

Si tu vois Hello from Docker! — tu es prêt.

Étape 2 — Cloner et analyser le projet Flask

On part d’un projet existant, comme tu le ferais dans une vraie mission.

git clone https://github.com/gothinkster/flask-realworld-example-app.git
cd flask-realworld-example-app

Avant de toucher quoi que ce soit, lis ces trois fichiers :

cat requirements.txt   # Les dépendances Python
cat autoapp.py         # Le point d'entrée de l'app
cat README.md          # La documentation existante

Ce réflexe — lire avant d’agir — est la marque d’un développeur qui pense avant de coder. C’est ce que cherche un tech lead.

La structure du projet :

flask-realworld-example-app/
├── autoapp.py          ← Point d'entrée Flask
├── requirements.txt    ← Dépendances Python
└── conduit/            ← Code de l'API

Étape 3 — Écrire le Dockerfile

C’est l’étape centrale. Chaque instruction a une raison précise.

# Image de base : Python 3.10 allégée (150 Mo au lieu de 900 Mo)
FROM python:3.10-slim

# Dossier de travail dans le container
WORKDIR /app

# ÉTAPE CLÉE : copier requirements.txt EN PREMIER
COPY requirements.txt .

# Installer les dépendances sans cache pip
RUN pip install --no-cache-dir -r requirements.txt

# Installer Gunicorn — le serveur de production
RUN pip install gunicorn

# Copier le code APRÈS les dépendances
COPY . .

# Documenter le port utilisé
EXPOSE 5000

# Démarrer avec Gunicorn
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "autoapp:app"]

Pourquoi cet ordre précis ?

Docker construit l’image couche par couche. Chaque instruction crée une couche mise en cache.

Si tu copies tout le code d’abord (COPY . .), puis tu fais pip install — le moindre changement dans ton code invalide le cache et force une réinstallation complète de toutes les dépendances.

En copiant requirements.txt seul en premier, le pip install n’est relancé que si les dépendances changent. Si tu modifies juste ton code — le rebuild passe directement au COPY . ..

30 secondes économisées à chaque rebuild. Sur 50 rebuilds par semaine, ça compte.

Pourquoi Gunicorn ?

Le serveur intégré de Flask (flask run) est :

  • Mono-thread (une requête à la fois)
  • Non sécurisé pour la production
  • Prévu uniquement pour le développement

Gunicorn gère plusieurs workers en parallèle et est conçu pour la production.

Pourquoi 0.0.0.0 ?

127.0.0.1 = accessible uniquement de l’intérieur du container → invisible depuis ton navigateur.
0.0.0.0 = accessible depuis l’extérieur → le port mapping fonctionne.

Étape 4 — Créer le .dockerignore

Sans ce fichier, Docker envoie tout ton dossier au moteur de build — y compris les fichiers inutiles ou dangereux.

# .dockerignore
venv/
.venv/
__pycache__/
*.pyc
.env
.git/
*.md

⚠️ .env dans ce fichier est critique. Sans ça, tes clés secrètes pourraient se retrouver dans l’image Docker publiée sur Docker Hub. Publiquement accessibles.

Étape 5 — Builder l’image

docker build -t mon-api-flask:v1 .

Observe les logs. Chaque step correspond à une instruction du Dockerfile.

Maintenant fais un second build sans rien changer :

docker build -t mon-api-flask:v1 .

Tu verras CACHED sur les steps pip install. Le cache fonctionne.

Vérifie l’image créée :

docker images
# REPOSITORY       TAG    SIZE
# mon-api-flask    v1     ~180MB

Étape 6 — Lancer le container et tester

# Lance le container
docker run -d -p 5000:5000 --name api-flask mon-api-flask:v1

# Vérifie qu'il tourne
docker ps

# Lis les logs Gunicorn
docker logs -f api-flask

Ouvre http://localhost:5000 dans ton navigateur. L’API répond.

Décryptage des flags docker run :

Flag Signification
-d Mode détaché — tourne en arrière-plan
-p 5000:5000 Port mapping hôte:container
--name api-flask Nom lisible au lieu d’un hash

Étape 7 — Sécuriser avec les variables d’environnement

# Crée le fichier de configuration
nano .env
FLASK_ENV=production
SECRET_KEY=change-cette-valeur-en-production
PORT=5000

Relance le container avec ces variables injectées :

docker stop api-flask && docker rm api-flask
docker run -d -p 5000:5000 --name api-flask --env-file .env mon-api-flask:v1

# Vérifie que les variables sont bien reçues
docker exec api-flask env

Le principe : l’image Docker ne contient jamais les valeurs sensibles. Elle les reçoit au moment du lancement. La même image peut tourner en dev, staging et production avec des configurations différentes.

Étape 8 — Publier sur Docker Hub

# Connexion
docker login

# Tag avec ton pseudo Docker Hub
docker tag mon-api-flask:v1 tonpseudo/mon-api-flask:v1

# Push
docker push tonpseudo/mon-api-flask:v1

Ton image est maintenant accessible depuis n’importe quel serveur dans le monde :

# Sur n'importe quelle machine avec Docker
docker pull tonpseudo/mon-api-flask:v1
docker run -d -p 5000:5000 tonpseudo/mon-api-flask:v1

C’est ça, la promesse de Docker : construis une fois, fais tourner partout.

Ce que ce projet t’a appris

Concept Ce que tu maîtrises maintenant
Layers Docker L’ordre des instructions = stratégie de cache
Port mapping -p hôte:container — sans ça, l’app est invisible
.dockerignore Protège les secrets, allège le build
Variables d’env Séparation config/code — principe 12-factor
Gunicorn Serveur WSGI de production pour Python
Docker Hub Registry public — le “GitHub” des images

Pour aller plus loin

  1. Docker Compose + PostgreSQL — Ajouter une base de données persistante connectée à Flask
  2. GitHub Actions CI/CD — Automatiser build + push à chaque git push
  3. Déploiement VPS — Nginx reverse proxy + HTTPS via Let’s Encrypt

Conclusion

Tu n’as plus besoin de dire “ça marchait chez moi”.

Ton app Flask est dans une boîte hermétique. Elle tourne sur ton Ubuntu, sur le serveur du client, sur la machine de ton collègue — de manière identique, sans rien réinstaller.

C’est exactement ce qu’un client freelance ou un recruteur veut voir : pas juste du code qui tourne en local, mais un artefact déployable et professionnel.

Le projet est sur GitHub et l’image sur Docker Hub — liens en fin d’article.

Roméo DOSSOU — Cloud & DevSecOps Engineer | Ouidah, Bénin
Je publie des guides pratiques Docker, Kubernetes et Cloud pour les ingénieurs francophones africains.

Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post

OpenAI proposed donating 5% of its equity to a US sovereign wealth fund

Next Post

Industry 4.0 Club Announces Inaugural Advisory Board to Strengthen Global Manufacturing Community

Related Posts