🐋 Docker / Compose | 🛡️ Nginx (Gateway, TLS, Auth, LB, Rate Limit, A/B) | 🐍 FastAPI (v1 + v2) | 🔥 Prometheus | 📊 Grafana
This repository implements the exam requirements:
- Reverse Proxy: Nginx is the single entry point for
/predict. - Load Balancing:
api-v1runs as 3 replicas behind an Nginx upstream. - HTTPS: TLS termination on Nginx with self-signed certs; HTTP redirects to HTTPS.
- Access Control:
/predictprotected by Basic Auth. - Rate Limiting:
/predictlimited to protect the backend. - A/B Testing:
api-v2is used only when headerX-Experiment-Group: debugis present. - Monitoring (Bonus): Nginx metrics → exporter → Prometheus → Grafana.
[ CLIENT ]
|
HTTPS :443
|
+---------v----------+
| 🛡️ NGINX GATEWAY |
| TLS / Auth / RL / |
| LB / A/B routing |
+----+----------+----+
| |
| +-------------------+
| |
v v
+-------------------+ +-------------------+
| 🐍 api-v1 (x3) | | 🐍 api-v2 (debug) |
| load-balanced | | header-triggered |
+-------------------+ +-------------------+
Metrics (pull-based; internal status is NOT published to host):
┌────────────────────────┐
│ 🎨 Grafana dashboards │ :3000
│ queries Prometheus API │
└───────────┬────────────┘
│ Prometheus query API (READ)
v
(1) scrape_interval
┌───────────────────────────────────────────┐
│ 🔥 Prometheus │ :9090
│ schedules scrapes + scrapes reporter │
│ + stores time series │
└───────────────┬───────────────────────────┘
│ (2) HTTP GET /metrics (PULL)
v
┌───────────────────────┐
│ 📊 nginx_exporter │ :9113
│ converts Nginx stats │
└───────────┬───────────┘
│ (3) HTTP GET /nginx_status (PULL)
v
┌───────────────────────────┐
│ 🛡️ NGINX :8081 │
│ /nginx_status (stub) │
│ allow: 127.0.0.1 + RFC1918│
└───────────────────────────┘
.
├── deployments/
│ ├── nginx/
│ │ ├── Dockerfile
│ │ ├── nginx.conf
│ │ ├── .htpasswd
│ │ └── certs/ (generated locally)
│ └── prometheus/
│ └── prometheus.yml
├── model/
│ └── model.joblib
├── src/
│ └── api/
│ ├── requirements.txt
│ ├── v1/ (FastAPI app + Dockerfile)
│ └── v2/ (FastAPI app + Dockerfile)
├── tests/
│ └── run_tests.sh
├── docker-compose.yml
├── Makefilemake gen-certsmake start-project
make linksmake testmake stop-projectcurl -s -X POST "https://localhost/predict" \
--cacert ./deployments/nginx/certs/nginx.crt \
--user admin:admin \
-H "Content-Type: application/json" \
-d '{"sentence": "Oh yeah, that was soooo cool!"}'curl -s -X POST "https://localhost/predict" \
--cacert ./deployments/nginx/certs/nginx.crt \
--user admin:admin \
-H "X-Experiment-Group: debug" \
-H "Content-Type: application/json" \
-d '{"sentence": "Oh yeah, that was soooo cool!"}'A burst of requests should produce a mix of 200 and 503 once the limit is exceeded.
The automated test suite (make test) includes a burst step and checks that the service remains available.
- Exporter: http://localhost:9113/metrics
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000 (admin / admin)
In Prometheus, check /targets → exporter should be UP.
make start-project— build + start full stack (api-v1 scaled to 3)make stop-project— stop stackmake test— runtests/run_tests.sh(grader entry point)make logs— follow logsmake links— print local URLs
The internal-only metrics endpoint (listen 8081 → /nginx_status) is not published to the host. It is meant to be reachable only inside the Docker network (for the exporter), not from the public/host side.
To keep this portable across different Docker/Compose subnets, the allowlist uses RFC1918 private ranges (commonly used by Docker bridge networks) plus loopback:
- 127.0.0.1 (inside-container calls)
- 172.16.0.0/12 and 192.168.0.0/16 (RFC1918 private ranges)
RFC1918 explicitly defines the private blocks, including 172.16/12, and 192.168/16: https://www.rfc-editor.org/rfc/rfc1918.txt
🇫🇷 Version Française
Pour cet examen, vous allez mettre en œuvre une architecture MLOps robuste et sécurisée. Le cœur du projet est d'utiliser Nginx comme une API Gateway pour servir un modèle de Machine Learning via une API FastAPI. Vous devrez non seulement rendre le service fonctionnel, mais aussi implémenter des fonctionnalités avancées essentielles en production : scalabilité, sécurité, et stratégies de déploiement modernes.
Votre mission est de configurer une architecture conteneurisée complète qui remplit les objectifs suivants :
-
Proxy Inverse (Reverse Proxy) : Nginx doit agir comme le seul point d'entrée et router le trafic vers les services API appropriés.
-
Équilibrage de Charge (Load Balancing) : L'API principale (
api-v1) doit être déployée en plusieurs instances (3 répliques) pour garantir la haute disponibilité et la répartition de la charge. -
Sécurité HTTPS : Toutes les communications externes doivent être chiffrées via HTTPS. Vous générerez des certificats auto-signés pour cela. Le trafic HTTP simple devra être automatiquement redirigé vers HTTPS.
-
Contrôle d'Accès : L'accès au point de terminaison de prédiction (
/predict) doit être protégé par une authentification basique (nom d'utilisateur / mot de passe). -
Limitation de Débit (Rate Limiting) : Pour protéger l'API contre les surcharges, l'endpoint
/predictdoit limiter le nombre de requêtes (ex: 10 requêtes/seconde par IP). -
A/B Testing : Vous déploierez deux versions de l'API.
api-v1: La version standard.api-v2: Une version "debug" qui retourne des informations supplémentaires.- Nginx devra router le trafic vers
api-v2uniquement si la requête contient l'en-tête HTTPX-Experiment-Group: debug. Sinon, le trafic doit aller versapi-v1.
-
Monitoring (Bonus) : Mettre en place une stack de monitoring avec Prometheus et Grafana pour collecter et visualiser les métriques de Nginx.
Le schéma suivant illustre l'architecture complète que vous devez construire. Nginx sert de passerelle centrale, gérant le trafic vers les différentes versions de l'API et exposant les métriques pour le monitoring.
graph TD
subgraph "Utilisateur"
U[Client] -->|Requête HTTPS| N
end
subgraph "Infrastructure Conteneurisée (Docker)"
N[Nginx Gateway] -->|Load Balancing| V1
N -->|"A/B Test (Header)"| V2
subgraph "API v1 (Scalée)"
V1[Upstream: api-v1]
V1_1[Replica 1]
V1_2[Replica 2]
V1_3[Replica 3]
V1 --- V1_1
V1 --- V1_2
V1 --- V1_3
end
subgraph "API v2 (Debug)"
V2[Upstream: api-v2]
end
subgraph "Stack de Monitoring"
N -->|/nginx_status| NE[Nginx Exporter]
NE -->|Métriques| P[Prometheus]
P -->|Source de données| G[Grafana]
U_Grafana[Admin] -->|Consulte Dashboards| G
end
end
style N fill:#269539,stroke:#333,stroke-width:2px,color:#fff
style G fill:#F46800,stroke:#333,stroke-width:2px,color:#fff
style P fill:#E6522C,stroke:#333,stroke-width:2px,color:#fff
Voici l'arborescence de fichiers que vous devez obtenir à la fin :
.
├── Makefile
├── README.md
├── README_student.md
├── data
│ └── tweet_emotions.csv
├── deployments
│ ├── nginx
│ │ ├── Dockerfile
│ │ ├── certs
│ │ │ ├── nginx.crt
│ │ │ └── nginx.key
│ │ └── nginx.conf
│ └── prometheus
│ └── prometheus.yml
├── docker-compose.yml
├── model
│ └── model.joblib
├── src
│ ├── api
│ │ ├── requirements.txt
│ │ ├── v1
│ │ │ ├── Dockerfile
│ │ │ └── main.py
│ │ └── v2
│ │ ├── Dockerfile
│ │ └── main.py
│ └── gen_model.py
└── tests
└── run_tests.shVous devez soumettre une archive .zip ou .tar.gz contenant l'intégralité de votre projet, incluant :
- Tous les
Dockerfilesnécessaires pour construire les images de vos services. - Le fichier
docker-compose.ymlorchestrant tous les services (Nginx, api-v1, api-v2, monitoring). - Le fichier
nginx.confcomplet avec toutes les directives requises. - Les fichiers de configuration et de sécurité (
.htpasswd, certificats SSL,prometheus.yml). - Le code source des deux versions de l'API.
- Un
Makefileavec des commandes claires pourstart-project,stop-project, ettest. - Un script de test (
tests/run_tests.sh) qui valide automatiquement les fonctionnalités clés.
Important : La validation finale de votre projet se fera en exécutant la commande make test. Celle-ci doit s'exécuter sans erreur et tous les tests doivent passer avec succès.
- Fonctionnalité : Toutes les fonctionnalités (de 1 à 6) sont implémentées et fonctionnent correctement.
- Qualité du Code : Les fichiers de configuration (
nginx.conf,docker-compose.yml) sont clairs, commentés si nécessaire, et bien structurés. - Reproductibilité : Le projet peut être lancé sans erreur avec
make start-project. - Automatisation : Le
Makefileet le script de test sont efficaces et permettent de valider le projet facilement. - Clarté de la Documentation : Le
README.mdprincipal explique clairement l'architecture et l'utilisation du projet.
Bon courage ! 🚀
🇬🇧 English Version
For this exam, you will implement a robust and secure MLOps architecture. The core of the project is to use Nginx as an API Gateway to serve a Machine Learning model via a FastAPI API. You will not only make the service functional but also implement advanced features essential for production: scalability, security, and modern deployment strategies.
Your mission is to set up a complete containerized architecture that meets the following objectives:
-
Reverse Proxy: Nginx must act as the single point of entry and route traffic to the appropriate API services.
-
Load Balancing: The main API (
api-v1) must be deployed in multiple instances (3 replicas) to ensure high availability and load distribution. -
HTTPS Security: All external communications must be encrypted via HTTPS. You will generate self-signed certificates for this purpose. Plain HTTP traffic must be automatically redirected to HTTPS.
-
Access Control: Access to the prediction endpoint (
/predict) must be protected by basic authentication (username/password). -
Rate Limiting: To protect the API from overload, the
/predictendpoint must limit the number of requests (e.g., 10 requests/second per IP). -
A/B Testing: You will deploy two versions of the API.
api-v1: The standard version.api-v2: A "debug" version that returns additional information.- Nginx must route traffic to
api-v2only if the request contains theX-Experiment-Group: debugHTTP header. Otherwise, traffic should be routed toapi-v1.
-
Monitoring (Bonus): Set up a monitoring stack with Prometheus and Grafana to collect and visualize Nginx metrics.
The following diagram illustrates the complete architecture you need to build. Nginx acts as a central gateway, managing traffic to the different API versions and exposing metrics for monitoring.
graph TD
subgraph "User"
U[Client] -->|HTTPS Request| N
end
subgraph "Containerized Infrastructure (Docker)"
N[Nginx Gateway] -->|Load Balancing| V1
N -->|"A/B Test (Header)"| V2
subgraph "API v1 (Scaled)"
V1[Upstream: api-v1]
V1_1[Replica 1]
V1_2[Replica 2]
V1_3[Replica 3]
V1 --- V1_1
V1 --- V1_2
V1 --- V1_3
end
subgraph "API v2 (Debug)"
V2[Upstream: api-v2]
end
subgraph "Monitoring Stack"
N -->|/nginx_status| NE[Nginx Exporter]
NE -->|Metrics| P[Prometheus]
P -->|Data Source| G[Grafana]
U_Grafana[Admin] -->|View Dashboards| G
end
end
style N fill:#269539,stroke:#333,stroke-width:2px,color:#fff
style G fill:#F46800,stroke:#333,stroke-width:2px,color:#fff
style P fill:#E6522C,stroke:#333,stroke-width:2px,color:#fff
Here is the file tree you should aim to have at the end:
.
├── Makefile
├── README.md
├── README_student.md
├── data
│ └── tweet_emotions.csv
├── deployments
│ ├── nginx
│ │ ├── Dockerfile
│ │ ├── certs
│ │ │ ├── nginx.crt
│ │ │ └── nginx.key
│ │ └── nginx.conf
│ └── prometheus
│ └── prometheus.yml
├── docker-compose.yml
├── model
│ └── model.joblib
├── src
│ ├── api
│ │ ├── requirements.txt
│ │ ├── v1
│ │ │ ├── Dockerfile
│ │ │ └── main.py
│ │ └── v2
│ │ ├── Dockerfile
│ │ └── main.py
│ └── gen_model.py
└── tests
└── run_tests.shYou must submit a .zip or .tar.gz archive containing your entire project, including:
- All necessary
Dockerfilesto build the images for your services. - The
docker-compose.ymlfile orchestrating all services (Nginx, api-v1, api-v2, monitoring). - The complete
nginx.conffile with all required directives. - Configuration and security files (
.htpasswd, SSL certificates,prometheus.yml). - The source code for both API versions.
- A
Makefilewith clear commands forstart-project,stop-project, andtest. - A test script (
tests/run_tests.sh) that automatically validates the key features.
Important: The final validation of your project will be done by running the make test command. It must run without errors, and all tests must pass successfully.
- Functionality: All features (1 through 6) are implemented and work correctly.
- Code Quality: Configuration files (
nginx.conf,docker-compose.yml) are clear, commented where necessary, and well-structured. - Reproducibility: The project can be launched without errors using
make start-project. - Automation: The
Makefileand test script are effective and allow for easy project validation. - Documentation Clarity: The main
README.mdclearly explains the project's architecture and usage.
Good luck! 🚀