Présentation du projet
Ce projet consiste à déployer Nginx Proxy Manager sous Docker pour centraliser la gestion des proxies inverses, des certificats SSL/TLS et des routes de trafic vers plusieurs applications backend.
Objectifs
- Déployer Nginx Proxy Manager avec Docker et Docker Compose
- Configurer des proxy hosts pour applications internes
- Gérer les certificats SSL/TLS avec Let’s Encrypt
- Mettre en place l’authentification et limiter la bande passante
- Monitorer les hosts et les certificats
Contexte technique
Problématique
- Gestion SSL complexe : certificats à renouveler manuellement
- Fragmentation : plusieurs applications sur différents ports/serveurs
- Accès externe : besoin d’exposer des services internes de manière sécurisée
- Scalabilité : ajouter une nouvelle application est complexe
- Coûts : plusieurs proxies vs une solution centralisée
Solution mise en œuvre
Nginx Proxy Manager offre :
- Interface Web : gestion facile sans fichiers de config
- Let’s Encrypt : certificats SSL auto-renouvelés
- Authentification : accès sécurisé avec login
- Wildcard Domains : *.example.com avec un seul certificat
- Docker : déploiement facile et isolé
- Haute disponibilité : load balancing simple
Réalisation technique
Architecture
Internet (Port 80/443)
↓
Nginx Proxy Manager (conteneur Docker)
↓
┌─────────────────────────────────────┐
├─ app1.example.com → 192.168.1.10:3000
├─ app2.example.com → 192.168.1.20:8080
├─ api.example.com → 192.168.1.5:5000
└─ dashboard.example.com → 192.168.1.30:90001. Prérequis
- Docker et Docker Compose installés
- Domaine configuré avec DNS pointant vers serveur
- Ports 80 et 443 ouverts sur le firewall
- Au minimum 2 GB RAM, 5 GB disque
- Accès à enregistrements DNS (pour ACME challenge)2. Créer le fichier docker-compose.yml
version: '3'
services:
db:
image: mysql:8.0
container_name: npm_db
restart: unless-stopped
environment:
MYSQL_USER: npm_user
MYSQL_PASSWORD: npm_secure_password
MYSQL_ROOT_PASSWORD: mysql_root_password
MYSQL_DATABASE: npm_db
volumes:
- ./data/mysql:/var/lib/mysql
networks:
- npm_network
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: npm_app
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
environment:
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: npm_user
DB_MYSQL_PASSWORD: npm_secure_password
DB_MYSQL_NAME: npm_db
DISABLE_IPV6: 'true'
volumes:
- ./data/npm/data:/data
- ./data/npm/letsencrypt:/etc/letsencrypt
depends_on:
- db
networks:
- npm_network
networks:
npm_network:
driver: bridge3. Déployer les conteneurs
# Créer un dossier pour les données
mkdir -p npm_data/mysql npm_data/npm/{data,letsencrypt}
# Placer le docker-compose.yml dans npm_data/
cd npm_data
# Démarrer les services
docker-compose up -d
# Vérifier le statut
docker-compose ps
# Voir les logs
docker-compose logs -f app4. Accès initial
URL: http://localhost:81
Identifiants par défaut:
Email: admin@example.com
Password: changeme
⚠️ Changer le mot de passe immédiatement!5. Configuration initiale
Changer le mot de passe administrateur:
User > Profile
Changer le mot de passe
Utiliser un mot de passe fort (16+ caractères)Ajouter un nom de domaine:
Settings > Default Site
Changer si besoin le nom de domaine par défaut6. Créer un Proxy Host
Exposer une application web (exemple: Portainer sur port 9000)
Hosts > Proxy Hosts > Add Proxy Host
Details:
Domain Names: portainer.example.com
Scheme: http
Forward Hostname: 192.168.1.30
Forward Port: 9000
Cache Assets: ✓ (optionnel)
Block Common Exploits: ✓ (sécurité)
SSL:
SSL Certificate: Request a new SSL Certificate
Force SSL: ✓ (rediriger HTTP → HTTPS)
Email for Let's Encrypt: admin@example.com
I agree to the Let's Encrypt Terms of Service: ✓
Use a DNS challenge: (si accès DNS)
Advanced:
Preserve Host Header: ✓
Websockets Support: ✓ (si needed)
SaveExemple : Application Node.js interne
Details:
Domain Names: app.example.com
Scheme: http
Forward Hostname: 192.168.1.10
Forward Port: 3000
Block Common Exploits: ✓
SSL:
Certificate: Request a new (Let's Encrypt)
Force SSL: ✓
Access List:
Access List: (optionnel) - restreindre à IPs spécifiques
Custom Locations:
Path: /api
Scheme: http
Forward Hostname: 192.168.1.5
Forward Port: 5000
(reroutage du /api vers serveur différent)
Save7. Authentification et contrôle d’accès
Ajouter authentification Basic Auth
Proxy Hosts > Edit > Access
Authentication: Basic Auth
Credentials: Créer ou sélectionner existant
Ou créer nouveau :
Username: user
Password: secure_passwordRestreindre par adresse IP
Proxy Hosts > Edit > Access
Access List: Create new
Name: "Office IPs"
Addresses: 203.0.113.0/24 (IP bureau)
Appliquer à tous les hosts sensibles8. Gestion des certificats SSL
Renouvellement automatique
Le renouvellement est automatique 30 jours avant expiration
Vérifier dans: SSL Certificates > Voir les certificats
Interface montre:
- Date d'émission
- Date d'expiration
- Domaines couverts
- Statut (Valid/Expiring soon)Certificat Wildcard
Details:
Domain Names: example.com, *.example.com
SSL:
Certificate: Request new wildcard
Email: admin@example.com
DNS Provider: (sélectionner pour ACME challenge)
Note: Wildcard couvre app1.example.com, app2.example.com, etc9. Configuration avancée
Rate Limiting (limiter bande passante)
Proxy Hosts > Edit > Advanced
Limit Connections: 50
Limit Rate: 10m (maximum 10 megabits par minute)Compression de réponse
Advanced:
Compression: ✓
Compression Types: application/json, text/html, text/css, etcRedirection
Hosts > Redirects > Add Redirect
Source URL: blog.example.com
Destination URL: example.com/blog
Force HTTPS: ✓10. Monitorer les proxy hosts
Dashboard
Home > Dashboard
Affiche:
- Nombre de proxy hosts actifs/inactifs
- Certificats proches de l'expiration
- Dernières actionsVérifier la santé d’un host
Proxy Hosts > Voir liste
Colonne Status:
🟢 Green: Certificat valide, host sain
🟡 Yellow: Certificat expire bientôt
🔴 Red: Problème de certificat ou proxy11. Backup et restauration
Sauvegarder la configuration
# Arrêter les conteneurs
docker-compose stop
# Créer une archive
tar -czf npm_backup_$(date +%Y%m%d).tar.gz npm_data/
# Vérifier
ls -lh npm_backup_*.tar.gzRestaurer depuis une sauvegarde
# Extraire
tar -xzf npm_backup_20240315.tar.gz
# Redémarrer
docker-compose up -d
# Vérifier
docker-compose logs appRésultats obtenus
✅ Nginx Proxy Manager déployé en Docker ✅ Base de données MySQL configurée ✅ Proxy hosts créés pour applications ✅ Certificats SSL/TLS automatisés (Let’s Encrypt) ✅ Authentification mise en place ✅ Accès sécurisé depuis Internet
Compétences développées
- Déploiement Docker et Docker Compose
- Gestion de proxies inverses (reverse proxy)
- Configuration SSL/TLS et Let’s Encrypt
- Authentification et contrôle d’accès
- Networking Docker
- Monitoring et troubleshooting
- Backup/restauration de configuration
Commandes Docker utiles
# Voir les conteneurs
docker ps
# Voir les logs
docker-compose logs -f app
# Redémarrer
docker-compose restart app
# Entrer dans le conteneur
docker exec -it npm_app /bin/bash
# Vérifier la base de données
docker exec npm_db mysql -u npm_user -p npm_db
# Nettoyer (attention!)
docker-compose down -v # Supprime tout!Troubleshooting
Certificat Let’s Encrypt échoue
1. Vérifier DNS pointe vers proxy manager
nslookup app.example.com
2. Vérifier ports 80/443 ouverts
telnet example.com 80
3. Voir logs détaillés
docker-compose logs app | grep "acme\|challenge"
4. Attendre 1h avant nouveau try (limite Let's Encrypt)Proxy ne peut pas atteindre backend
1. Vérifier adresse IP/port du backend
ping 192.168.1.10
telnet 192.168.1.10 3000
2. Vérifier DNS résolution depuis conteneur
docker exec npm_app nslookup backend.local
3. Vérifier networking:
docker network inspect npm_network
4. Backend défaut doit être accessible
http://192.168.1.10:3000Performance lente
1. Vérifier ressources Docker:
docker stats
2. Augmenter dans docker-compose:
memory: 512M
cpus: '1'
3. Réduire compression pour CPU:
Advanced > Compression: OFF
4. Vérifier bande passante réseau
iftop -i eth0Bonnes pratiques
✅ FAIRE:
- Sauvegarder régulièrement la config
- Monitorer certificats proches de l'expiration
- Utiliser authentification sur services sensibles
- Activer "Block Common Exploits"
- Tester accès depuis Internet
- Mettre à jour container régulièrement
- Utiliser volumes pour données persistantes
❌ ÉVITER:
- Exposer directement des services sans proxy
- Désactiver SSL/TLS
- Utiliser mots de passe par défaut
- Laisser ports non-nécessaires ouverts
- Proxifier des services locaux sans besoinPerspectives d’amélioration
- Intégration avec Fail2Ban pour ban d’IPs
- Metrics Prometheus pour monitoring
- Backup automatique vers cloud
- Haute disponibilité (2 instances)
- Audit logging centralisé
- Integration SSO (OIDC/SAML)
- Custom headers et redirects avancés
- Validation de certificats SAN
Coûts et alternatives
Nginx Proxy Manager:
✅ Gratuit, open-source
✅ Interface simple
✅ Let's Encrypt gratuit
❌ Moins de features que HAProxy
Autres outils:
- HAProxy : plus puissant, plus complexe
- Traefik : orchestration K8s native
- Caddy : automatisation SSL simplifiée
- Apache reverse proxy : lourd mais stableConclusion
Nginx Proxy Manager simplifie drastiquement la gestion des proxies et certificats SSL. Parfait pour exposer des applications internes via HTTPS avec authentification, le tout via une interface web conviviale.
