Tuto : Load balancer avec Nginx dans un unique container Docker
Ce tuto concerne la mise en place à titre d’illustration d’un load balancer pour en comprendre les principes, dans un seul container docker. Dans ce container docker, il ya aura Linux Debian et tous les programmes nécessaires, dont Nginx bien sûr, mais aussi Supervisor. En effet faire tourner dans un docker Nginx et plusieurs instances de serveur n’est pas très compatible, puisque Docker n’assure qu’un process, dans le cas du load balancer on a Nginx et trois instances de serveur.
Supervisor permet de gérer à l’instar de SystemD les process, c’est un programme qui manage les autres programmes.
On se procure l’image Docker de Debian Linux officiel
docker pull debian docker run -it debian
Ensuite on installe les programmes nécessaire pour faire tourner le load balancer
// ici on installe dans le docker les programmes nécessaire // mise à jour de la BDD des packages apt update apt install nginx python3 supervisor curl
Configuration du fichier supervisord.conf
Tout d’abord nous allons créer deux répertoires, un pour stocker le fichier de configuration, et un pour les logs
mkdir -p /etc/supervisor/conf.d/ mkdir -p /var/log/supervisor/ // créons le fichier de configuration qui n'existe pas au début nano /etc/supervisor/conf.d/supervisord.conf
[supervisord] nodaemon=true user=root [program:nginx] command=nginx -g "daemon off;" autostart=true autorestart=true stderr_logfile=/var/log/supervisor/nginx_err.log stdout_logfile=/var/log/supervisor/nginx_out.log [program:python-server-1] command=python3 /app/app.py 8001 directory=/app autostart=true autorestart=true stderr_logfile=/var/log/supervisor/python1_err.log stdout_logfile=/var/log/supervisor/python1_out.log [program:python-server-2] command=python3 /app/app.py 8002 directory=/app autostart=true autorestart=true stderr_logfile=/var/log/supervisor/python2_err.log stdout_logfile=/var/log/supervisor/python2_out.log [program:python-server-3] command=python3 /app/app.py 8003 directory=/app autostart=true autorestart=true stderr_logfile=/var/log/supervisor/python3_err.log stdout_logfile=/var/log/supervisor/python3_out.log
Le fichier de Supervisor démarre les 3 serveurs python, nous allons faire le script de serveur Python
Script Python du serveur
// Création du répertoire de l'application
mkdir -p /app
nano /app/app.py
// code du fichier serveur minimal
#!/usr/bin/env python3
import http.server
import socketserver
import sys
# Get port from command line argument
PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8001
class MyHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
response = f"""
<h1>Hello from Server {PORT}</h1>
<p>Server ID: {PORT}</p>
<p>Path: {self.path}</p>
"""
self.wfile.write(response.encode())
if __name__ == '__main__':
with socketserver.TCPServer(("", PORT), MyHandler) as httpd:
print(f"Server running on port {PORT}")
httpd.serve_forever()
Configuration de Nginx
events {
worker_connections 1024;
}
http {
# Define upstream servers (Python backends)
upstream backend {
server 127.0.0.1:8001;
server 127.0.0.1:8002;
server 127.0.0.1:8003;
# Load balancing method options:
# least_conn; # Route to server with fewest active connections
# ip_hash; # Route based on client IP (sticky sessions)
# Default is round-robin
}
# Health check configuration
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Connection and timeout settings
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Health check
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
}
# Health check endpoint
location /health {
access_log off;
return 200 "OK\n";
add_header Content-Type text/plain;
}
}
}
Lancement du serveur Nginx
comme on n'a pas systemd on lance en direct depuis Supervisor sudo supervisord -c /etc/supervisor/conf.d/supervisord.conf
Normalement tous les services sont lancés, et vous pouvez faire un curl pour tester le serveur frontal
curl http://localhost
<h1>Hello from Server 8001</h1>
<p>Server ID: 8001</p>
<p>Path: /</p>
curl http://localhost
<h1>Hello from Server 8002</h1>
<p>Server ID: 8002</p>
<p>Path: /</p>
curl http://localhost
<h1>Hello from Server 8003</h1>
<p>Server ID: 8003</p>
<p>Path: /</p>
curl http://localhost
<h1>Hello from Server 8001</h1>
<p>Server ID: 8001</p>
<p>Path: /</p>
Là nous voyons quelque chose de très intéressant, on requête la même url, mais ce n’est pas le même serveur qui nous retourne la réponse. Vous y êtes !
Et maintenant?
Là nous avons un seul container docker, c’est de l’expérience de laboratoire. Le docker est là pour des raisons de convénience, nonobstant la plateforme (mac, linux ou Windows) vous pouvez faire les mêmes commandes.
Vous pouvez faire ce tuto dans WSL, dans Linux. Cependant voyons quels scénarios nous pouvons explorer
-Load balancing vers des serveurs dans d’autres containers docker au sein d’une même plateforme.
-load balancing vers des serveurs par leurs urls
ff








