Apache / Nginx
- 1. Installation Apache
- 2. Structure des fichiers de configuration
- 3. VirtualHosts (HTTP et HTTPS)
- 4. Modules (a2enmod, a2dismod, mod_rewrite, mod_ssl, mod_proxy)
- 5. .htaccess (rewrite, redirections, protection)
- 6. Reverse Proxy avec Apache
- 7. SSL/TLS avec Let's Encrypt
- 8. Installation Nginx
- 9. Configuration server blocks
- 10. Reverse Proxy avec Nginx
- 11. SSL/TLS avec Nginx
- 12. Comparaison Apache vs Nginx
- 13. Commandes de maintenance
- 14. Depannage (logs, configtest)
1. Installation Apache
1.1 Debian / Ubuntu
# Mise a jour des depots
sudo apt update
# Installation du paquet Apache2
sudo apt install apache2 -y
# Verifier que le service est actif
sudo systemctl status apache2
# Activer le demarrage automatique
sudo systemctl enable apache2
1.2 CentOS / RHEL / AlmaLinux
# Installation du paquet httpd
sudo dnf install httpd -y
# Demarrer le service
sudo systemctl start httpd
# Activer le demarrage automatique
sudo systemctl enable httpd
# Ouvrir les ports dans le firewall
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
1.3 Verification de l'installation
# Verifier la version installee
apache2 -v # Debian/Ubuntu
httpd -v # CentOS/RHEL
# Tester dans le navigateur
curl http://localhost
apache2. Sur CentOS/RHEL, il s'appelle httpd. Les commandes, fichiers de configuration et chemins different entre les deux familles.
ss -tlnp | grep :80.
2. Structure des fichiers de configuration
2.1 Arborescence Debian / Ubuntu
/etc/apache2/
├── apache2.conf # Configuration principale
├── ports.conf # Ports d'ecoute (Listen 80, Listen 443)
├── envvars # Variables d'environnement (APACHE_RUN_USER, etc.)
├── conf-available/ # Configurations supplementaires disponibles
├── conf-enabled/ # Configurations actives (liens symboliques)
├── mods-available/ # Modules disponibles (.load + .conf)
├── mods-enabled/ # Modules actifs (liens symboliques)
├── sites-available/ # VirtualHosts disponibles
│ ├── 000-default.conf # VirtualHost par defaut (port 80)
│ └── default-ssl.conf # VirtualHost SSL par defaut (port 443)
└── sites-enabled/ # VirtualHosts actifs (liens symboliques)
└── 000-default.conf
2.2 Arborescence CentOS / RHEL
/etc/httpd/
├── conf/
│ └── httpd.conf # Configuration principale (tout-en-un)
├── conf.d/ # Configurations supplementaires (*.conf)
│ ├── ssl.conf # Configuration SSL globale
│ └── welcome.conf # Page d'accueil par defaut
├── conf.modules.d/ # Chargement des modules (*.conf)
│ ├── 00-base.conf
│ ├── 00-ssl.conf
│ └── ...
└── modules/ # Lien vers /usr/lib64/httpd/modules/
2.3 Fichier apache2.conf - Directives importantes
# Timeout global (en secondes)
Timeout 300
# Connexions persistantes (Keep-Alive)
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
# Configuration du MPM (Multi-Processing Module)
# Fichier : /etc/apache2/mods-available/mpm_prefork.conf
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
# Interdire l'acces par defaut
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
# Autoriser le DocumentRoot
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
2.4 Fichier ports.conf
# Port HTTP standard
Listen 80
# Port HTTPS (uniquement si mod_ssl est charge)
<IfModule ssl_module>
Listen 443
</IfModule>
# Ajouter un port personnalise
Listen 8080
*-available / *-enabled avec des liens symboliques permet d'activer ou desactiver rapidement des sites, modules et configurations sans supprimer de fichiers. Utilisez les commandes a2ensite, a2dissite, a2enmod, a2dismod, a2enconf, a2disconf.
3. VirtualHosts (HTTP et HTTPS)
3.1 Concept
Un VirtualHost permet a Apache d'heberger plusieurs sites web sur un meme serveur. Chaque VirtualHost est associe a un nom de domaine (ou une IP) et definit sa propre configuration (DocumentRoot, logs, options, etc.).
3.2 VirtualHost HTTP simple (port 80)
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
ServerAdmin webmaster@example.com
DocumentRoot /var/www/example.com/public
<Directory /var/www/example.com/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>
3.3 VirtualHost HTTPS (port 443)
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/public
<Directory /var/www/example.com/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Configuration SSL
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
# En-tetes de securite
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
ErrorLog ${APACHE_LOG_DIR}/example.com-ssl-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-ssl-access.log combined
</VirtualHost>
</IfModule>
3.4 Redirection HTTP vers HTTPS
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
# Methode 1 : Redirect permanent
Redirect permanent / https://example.com/
# Methode 2 : RewriteRule (necessite mod_rewrite)
# RewriteEngine On
# RewriteCond %{HTTPS} off
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>
3.5 Activer / desactiver un VirtualHost
# Creer le fichier dans sites-available
sudo nano /etc/apache2/sites-available/example.com.conf
# Activer le site
sudo a2ensite example.com.conf
# Desactiver le site
sudo a2dissite example.com.conf
# Desactiver le site par defaut
sudo a2dissite 000-default.conf
# Toujours recharger apres modification
sudo systemctl reload apache2
3.6 Preparer le DocumentRoot
# Creer le repertoire du site
sudo mkdir -p /var/www/example.com/public
# Attribuer les droits
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
# Creer une page de test
echo "<h1>example.com fonctionne</h1>" | sudo tee /var/www/example.com/public/index.html
Options +Indexes en production. Cette directive permet le listage du contenu des repertoires et peut exposer des fichiers sensibles. Utilisez toujours Options -Indexes.
4. Modules (a2enmod, a2dismod, mod_rewrite, mod_ssl, mod_proxy)
4.1 Gestion des modules (Debian/Ubuntu)
# Lister les modules disponibles
ls /etc/apache2/mods-available/
# Lister les modules actifs
ls /etc/apache2/mods-enabled/
# ou
apache2ctl -M
# Activer un module
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers
sudo a2enmod proxy proxy_http
# Desactiver un module
sudo a2dismod autoindex
# Toujours redemarrer apres activation/desactivation de module
sudo systemctl restart apache2
4.2 Gestion des modules (CentOS/RHEL)
# Les modules sont charges dans /etc/httpd/conf.modules.d/
# Pour desactiver un module, commentez la ligne LoadModule
# Lister les modules charges
httpd -M
# Exemple : desactiver un module
sudo sed -i 's/^LoadModule autoindex_module/#LoadModule autoindex_module/' \
/etc/httpd/conf.modules.d/00-base.conf
sudo systemctl restart httpd
4.3 mod_rewrite - Reecriture d'URL
# Activer le module
sudo a2enmod rewrite
# Exemple dans un VirtualHost ou .htaccess
RewriteEngine On
# Redirection www vers non-www
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]
# URL propres (front controller pattern - ex: Laravel, Symfony)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?url=$1 [QSA,L]
4.4 mod_ssl - Chiffrement HTTPS
# Activer le module
sudo a2enmod ssl
# Verifier que le port 443 est bien configure dans ports.conf
# Listen 443
# Configuration SSL recommandee (dans le VirtualHost)
SSLEngine on
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES
SSLHonorCipherOrder on
# Activer HSTS
Header always set Strict-Transport-Security "max-age=63072000"
4.5 mod_proxy - Proxy et Reverse Proxy
# Activer les modules necessaires
sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests
# Configuration basique dans un VirtualHost
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
4.6 Autres modules utiles
# mod_headers : manipulation des en-tetes HTTP
sudo a2enmod headers
# mod_expires : controle du cache navigateur
sudo a2enmod expires
# mod_deflate : compression gzip des reponses
sudo a2enmod deflate
# mod_security2 : pare-feu applicatif (WAF)
sudo apt install libapache2-mod-security2
sudo a2enmod security2
# mod_evasive : protection contre les attaques DDoS
sudo apt install libapache2-mod-evasive
sudo a2enmod evasive
apache2ctl -M 2>/dev/null | sort. Les modules "static" sont compiles dans Apache, les "shared" sont charges dynamiquement.
5. .htaccess (rewrite, redirections, protection)
5.1 Prerequis
Pour que les fichiers .htaccess soient pris en compte, la directive AllowOverride doit etre configuree dans le VirtualHost :
<Directory /var/www/example.com/public>
# AllowOverride None = .htaccess ignore (meilleure performance)
# AllowOverride All = .htaccess pris en compte entierement
AllowOverride All
Require all granted
</Directory>
AllowOverride All a un impact sur les performances car Apache doit lire le fichier .htaccess a chaque requete dans chaque repertoire. En production, il est preferable de placer les regles directement dans le VirtualHost et d'utiliser AllowOverride None.
5.2 Reecriture d'URL
RewriteEngine On
# Forcer HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Forcer www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [L,R=301]
# URLs propres (front controller)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
# Supprimer l'extension .php de l'URL
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
5.3 Redirections
# Redirection 301 (permanente)
Redirect 301 /ancienne-page.html https://example.com/nouvelle-page.html
# Redirection 302 (temporaire)
Redirect 302 /promo https://example.com/soldes
# Redirection avec expression reguliere
RedirectMatch 301 ^/blog/([0-9]+)/(.*)$ https://example.com/articles/$1/$2
# Redirection de tout un repertoire
RedirectMatch 301 ^/ancien-repertoire/(.*)$ https://example.com/nouveau-repertoire/$1
5.4 Protection par mot de passe
# Dans le .htaccess
AuthType Basic
AuthName "Zone protegee"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
# Creer le fichier de mots de passe
sudo htpasswd -c /etc/apache2/.htpasswd utilisateur1
# Ajouter un utilisateur supplementaire (sans -c)
sudo htpasswd /etc/apache2/.htpasswd utilisateur2
5.5 Restriction d'acces par IP
# Autoriser uniquement certaines IP (Apache 2.4+)
<RequireAny>
Require ip 192.168.1.0/24
Require ip 10.0.0.50
</RequireAny>
# Bloquer une IP specifique
<RequireAll>
Require all granted
Require not ip 203.0.113.50
</RequireAll>
5.6 Protection de fichiers et repertoires
# Interdire l'acces aux fichiers .env, .git, etc.
<FilesMatch "^\.(?!well-known)">
Require all denied
</FilesMatch>
# Proteger un fichier specifique
<Files "config.php">
Require all denied
</Files>
# Interdire le listage des repertoires
Options -Indexes
# Interdire l'acces a certaines extensions
<FilesMatch "\.(sql|log|bak|old|env)$">
Require all denied
</FilesMatch>
5.7 Cache et compression
# Activer la compression gzip
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
# Configuration du cache navigateur
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType text/html "access plus 0 seconds"
</IfModule>
.htaccess sans impacter la production, utilisez le flag [R=302] (redirection temporaire) au lieu de [R=301] (permanente). Les navigateurs mettent en cache les 301, ce qui rend le debogage difficile.
6. Reverse Proxy avec Apache
6.1 Concept
Un reverse proxy est un serveur intermediaire qui recoit les requetes des clients et les transmet a un ou plusieurs serveurs backend. Le client ne communique jamais directement avec le backend. Cas d'usage typiques : application Node.js, API, Tomcat, serveur interne, etc.
6.2 Activer les modules necessaires
sudo a2enmod proxy proxy_http proxy_wstunnel proxy_balancer lbmethod_byrequests headers
sudo systemctl restart apache2
6.3 Reverse proxy simple
<VirtualHost *:80>
ServerName app.example.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
# Transmettre les en-tetes du client au backend
RequestHeader set X-Forwarded-Proto "http"
RequestHeader set X-Real-IP "%{REMOTE_ADDR}s"
ErrorLog ${APACHE_LOG_DIR}/app-proxy-error.log
CustomLog ${APACHE_LOG_DIR}/app-proxy-access.log combined
</VirtualHost>
6.4 Reverse proxy avec HTTPS en facade
<VirtualHost *:443>
ServerName app.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/app.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/app.example.com/privkey.pem
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ErrorLog ${APACHE_LOG_DIR}/app-ssl-proxy-error.log
CustomLog ${APACHE_LOG_DIR}/app-ssl-proxy-access.log combined
</VirtualHost>
6.5 Proxy vers un sous-chemin specifique
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/example.com/public
# Le site principal est servi normalement
# /api est proxy vers le backend Node.js
ProxyPass /api http://127.0.0.1:4000/api
ProxyPassReverse /api http://127.0.0.1:4000/api
# /admin est proxy vers un autre backend
ProxyPass /admin http://127.0.0.1:8080/admin
ProxyPassReverse /admin http://127.0.0.1:8080/admin
</VirtualHost>
6.6 Support WebSocket
<VirtualHost *:80>
ServerName ws.example.com
ProxyPreserveHost On
# Proxy WebSocket
RewriteEngine On
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) ws://127.0.0.1:3000/$1 [P,L]
# Proxy HTTP classique
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
</VirtualHost>
6.7 Load Balancing
<Proxy "balancer://moncluster">
BalancerMember http://127.0.0.1:3001
BalancerMember http://127.0.0.1:3002
BalancerMember http://127.0.0.1:3003
ProxySet lbmethod=byrequests
</Proxy>
<VirtualHost *:80>
ServerName app.example.com
ProxyPreserveHost On
ProxyPass / balancer://moncluster/
ProxyPassReverse / balancer://moncluster/
</VirtualHost>
ProxyRequests On sauf besoin explicite de forward proxy. Un forward proxy ouvert permet a n'importe qui d'utiliser votre serveur comme relais, ce qui constitue une faille de securite majeure.
7. SSL/TLS avec Let's Encrypt (Apache)
7.1 Installation de Certbot
# Methode recommandee : via snap
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# Installer le plugin Apache
sudo apt install python3-certbot-apache # Debian/Ubuntu
sudo dnf install python3-certbot-apache # CentOS/RHEL
7.2 Obtenir un certificat
# Certificat automatique (modifie le VirtualHost)
sudo certbot --apache -d example.com -d www.example.com
# Obtenir le certificat sans modifier Apache
sudo certbot certonly --apache -d example.com -d www.example.com
# Mode non-interactif (scripts / automatisation)
sudo certbot --apache --non-interactive --agree-tos \
--email admin@example.com -d example.com -d www.example.com
7.3 Renouvellement automatique
# Tester le renouvellement
sudo certbot renew --dry-run
# Le renouvellement est gere automatiquement par un timer systemd ou un cron
# Verifier le timer
sudo systemctl list-timers | grep certbot
# Ou ajouter un cron manuellement
# 0 3 * * * certbot renew --quiet --post-hook "systemctl reload apache2"
7.4 Configuration SSL renforcee
# Dans le VirtualHost SSL ou dans un fichier inclus
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
# En-tetes de securite
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "DENY"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
8. Installation Nginx
8.1 Debian / Ubuntu
# Installation depuis les depots officiels
sudo apt update
sudo apt install nginx -y
# Verifier le service
sudo systemctl status nginx
# Activer le demarrage automatique
sudo systemctl enable nginx
8.2 Depot officiel Nginx (version plus recente)
# Ajouter la cle GPG et le depot officiel Nginx
sudo apt install curl gnupg2 ca-certificates lsb-release
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor \
-o /usr/share/keyrings/nginx-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/debian $(lsb_release -cs) nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
sudo apt update
sudo apt install nginx -y
8.3 CentOS / RHEL / AlmaLinux
# Installation depuis EPEL
sudo dnf install epel-release
sudo dnf install nginx -y
# Demarrer et activer
sudo systemctl start nginx
sudo systemctl enable nginx
# Ouvrir les ports du firewall
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
8.4 Structure des fichiers Nginx
/etc/nginx/
├── nginx.conf # Configuration principale
├── mime.types # Types MIME
├── conf.d/ # Configurations supplementaires (*.conf)
│ └── default.conf # Server block par defaut
├── sites-available/ # Server blocks disponibles (Debian/Ubuntu)
├── sites-enabled/ # Server blocks actifs (liens symboliques)
├── snippets/ # Fragments de configuration reutilisables
│ ├── fastcgi-php.conf
│ └── snakeoil.conf
├── modules-available/ # Modules disponibles
└── modules-enabled/ # Modules actifs
8.5 Verification de l'installation
# Version installee
nginx -v
# Modules compiles
nginx -V
# Tester la configuration
sudo nginx -t
# Tester dans le navigateur
curl http://localhost
sites-available / sites-enabled similaire a Apache. Le paquet du depot nginx.org utilise uniquement conf.d/. Adaptez votre workflow en consequence.
9. Configuration server blocks
9.1 Concept
Les server blocks de Nginx sont l'equivalent des VirtualHosts d'Apache. Chaque server block definit la configuration pour un domaine specifique.
9.2 Server block HTTP simple
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.html index.htm index.php;
# Logs
access_log /var/log/nginx/example.com-access.log;
error_log /var/log/nginx/example.com-error.log;
# Gestion des fichiers statiques
location / {
try_files $uri $uri/ =404;
}
# Bloquer l'acces aux fichiers caches
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}
9.3 Server block avec PHP (PHP-FPM)
server {
listen 80;
server_name example.com;
root /var/www/example.com/public;
index index.php index.html;
# Traitement des requetes PHP via PHP-FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Front controller (Laravel, Symfony, etc.)
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Fichiers statiques : cache long
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
9.4 Activer / desactiver un server block
# Creer la configuration dans sites-available
sudo nano /etc/nginx/sites-available/example.com
# Activer (creer le lien symbolique)
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# Desactiver (supprimer le lien symbolique)
sudo rm /etc/nginx/sites-enabled/example.com
# Desactiver le site par defaut
sudo rm /etc/nginx/sites-enabled/default
# Tester la configuration AVANT de recharger
sudo nginx -t
# Recharger la configuration
sudo systemctl reload nginx
9.5 Directives de securite et optimisation
# Dans nginx.conf (bloc http)
http {
# Cacher la version de Nginx dans les en-tetes
server_tokens off;
# Taille maximale d'upload
client_max_body_size 50M;
# Compression gzip
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml image/svg+xml;
# Timeouts
client_body_timeout 12;
client_header_timeout 12;
keepalive_timeout 15;
send_timeout 10;
# Buffers
client_body_buffer_size 10K;
client_header_buffer_size 1k;
large_client_header_buffers 4 8k;
}
nginx -t avant de recharger. Contrairement a Apache, Nginx ne demarrera pas du tout si la configuration contient une erreur de syntaxe.
10. Reverse Proxy avec Nginx
10.1 Reverse proxy simple
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
10.2 Reverse proxy vers un sous-chemin
server {
listen 80;
server_name example.com;
root /var/www/example.com/public;
# Site principal
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# API vers un backend Node.js
location /api/ {
proxy_pass http://127.0.0.1:4000/api/;
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;
}
}
10.3 Support WebSocket
server {
listen 80;
server_name ws.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# En-tetes necessaires pour WebSocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Timeout pour les connexions longue duree
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
10.4 Load Balancing
# Definir le groupe de serveurs backend
upstream backend_cluster {
# Methodes de repartition :
# (defaut) round-robin
# least_conn; moins de connexions actives
# ip_hash; affinite par IP client
# hash $request_uri consistent; affinite par URI
least_conn;
server 127.0.0.1:3001 weight=3; # recoit 3x plus de trafic
server 127.0.0.1:3002;
server 127.0.0.1:3003;
server 127.0.0.1:3004 backup; # utilise uniquement si les autres sont down
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
10.5 Proxy avec cache
# Dans nginx.conf (bloc http) : definir la zone de cache
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mon_cache:10m
max_size=1g inactive=60m use_temp_path=off;
# Dans le server block
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_cache mon_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
# En-tete pour debugger le cache (HIT/MISS/BYPASS)
add_header X-Cache-Status $upstream_cache_status;
}
# Ne pas cacher les requetes API
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_cache off;
}
}
proxy_pass. proxy_pass http://backend/ (avec slash) remplace le chemin du location. proxy_pass http://backend (sans slash) conserve le chemin complet. Ce detail peut causer des problemes de routage subtils.
11. SSL/TLS avec Nginx
11.1 Obtenir un certificat avec Certbot
# Installer le plugin Nginx
sudo apt install python3-certbot-nginx # Debian/Ubuntu
sudo dnf install python3-certbot-nginx # CentOS/RHEL
# Obtenir et configurer automatiquement
sudo certbot --nginx -d example.com -d www.example.com
# Obtenir sans modifier la configuration Nginx
sudo certbot certonly --nginx -d example.com
11.2 Server block HTTPS complet
# Redirection HTTP vers HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
# Server block HTTPS
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.html index.php;
# Certificats SSL
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Parametres SSL recommandes
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# Cache de session SSL
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# En-tetes de securite
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
}
11.3 Reverse Proxy HTTPS
server {
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://127.0.0.1:3000;
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 https;
}
}
11.4 Generer des parametres Diffie-Hellman
# Generer un fichier dhparam (peut prendre plusieurs minutes)
sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
# Ajouter dans le server block SSL
ssl_dhparam /etc/nginx/dhparam.pem;
/etc/nginx/snippets/ssl-params.conf avec vos parametres SSL et incluez-le dans chaque server block avec include snippets/ssl-params.conf;. Cela evite la duplication et facilite la maintenance.
12. Comparaison Apache vs Nginx
12.1 Architecture
| Critere | Apache | Nginx |
|---|---|---|
| Modele | Processus/threads (MPM prefork, worker, event) | Evenementiel asynchrone (event-driven) |
| Connexions simultanees | 1 thread/processus par connexion (MPM prefork) | Des milliers de connexions par worker |
| Memoire | Consommation plus elevee sous forte charge | Empreinte memoire faible et stable |
| Fichiers statiques | Bonnes performances | Excellentes performances |
| Contenu dynamique | mod_php integre (simple) | Necessite un backend externe (PHP-FPM) |
12.2 Configuration et fonctionnalites
| Critere | Apache | Nginx |
|---|---|---|
| .htaccess | Supporte (configuration par repertoire) | Non supporte |
| Modules | Chargeables dynamiquement (a2enmod) | Compiles a la construction (sauf modules dynamiques recents) |
| Configuration | XML-like, flexible, distribue (.htaccess) | Blocs C-like, centralise, pas de .htaccess |
| Reverse Proxy | Bon (mod_proxy) | Excellent (natif, principal cas d'usage) |
| Load Balancing | Basique (mod_proxy_balancer) | Avance (upstream, health checks, etc.) |
| Documentation | Tres riche, communaute historique | Bonne, en croissance |
12.3 Quand utiliser lequel ?
- Apache : hebergement mutualise, besoin de .htaccess, applications PHP classiques (WordPress, etc.), compatibilite avec des configurations existantes, modules specifiques (mod_security, mod_pagespeed)
- Nginx : reverse proxy, load balancing, fort trafic sur fichiers statiques, architecture microservices, API gateway, sites a forte audience
- Combinaison Nginx + Apache : Nginx en facade (reverse proxy, fichiers statiques, SSL termination) et Apache en backend (contenu dynamique PHP avec mod_php). Cette architecture combine les forces des deux serveurs.
.htaccess.
13. Commandes de maintenance
13.1 Apache - Commandes essentielles
# --- Gestion du service ---
sudo systemctl start apache2 # Demarrer
sudo systemctl stop apache2 # Arreter
sudo systemctl restart apache2 # Redemarrer (coupe les connexions en cours)
sudo systemctl reload apache2 # Recharger la config (sans couper les connexions)
sudo systemctl status apache2 # Verifier le statut
# --- Test de configuration ---
sudo apache2ctl configtest # Debian/Ubuntu
sudo httpd -t # CentOS/RHEL
sudo apache2ctl -S # Afficher les VirtualHosts configures
# --- Gestion des sites ---
sudo a2ensite monsite.conf # Activer un site
sudo a2dissite monsite.conf # Desactiver un site
# --- Gestion des modules ---
sudo a2enmod rewrite # Activer un module
sudo a2dismod autoindex # Desactiver un module
apache2ctl -M # Lister les modules actifs
# --- Gestion des configurations ---
sudo a2enconf security # Activer une configuration
sudo a2disconf serve-cgi-bin # Desactiver une configuration
# --- Informations ---
apache2 -v # Version d'Apache
apache2 -V # Version + options de compilation
13.2 Nginx - Commandes essentielles
# --- Gestion du service ---
sudo systemctl start nginx # Demarrer
sudo systemctl stop nginx # Arreter
sudo systemctl restart nginx # Redemarrer
sudo systemctl reload nginx # Recharger la config (graceful)
sudo systemctl status nginx # Verifier le statut
# --- Test de configuration ---
sudo nginx -t # Tester la syntaxe de la configuration
sudo nginx -T # Tester et afficher toute la configuration
# --- Signaux Nginx ---
sudo nginx -s reload # Recharger (equivalent a systemctl reload)
sudo nginx -s stop # Arret immediat
sudo nginx -s quit # Arret graceful (attend la fin des requetes)
sudo nginx -s reopen # Reouverture des fichiers de log
# --- Gestion des sites (Debian/Ubuntu) ---
sudo ln -s /etc/nginx/sites-available/monsite /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/monsite
# --- Informations ---
nginx -v # Version de Nginx
nginx -V # Version + options de compilation
13.3 Gestion des logs
# --- Rotation des logs (logrotate) ---
# Apache : /etc/logrotate.d/apache2
# Nginx : /etc/logrotate.d/nginx
# Exemple de configuration logrotate personnalisee
# /etc/logrotate.d/monsite
/var/log/nginx/monsite-*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
endscript
}
# Forcer la rotation manuellement
sudo logrotate -f /etc/logrotate.d/nginx
13.4 Mise a jour
# Apache (Debian/Ubuntu)
sudo apt update && sudo apt upgrade apache2
# Nginx (Debian/Ubuntu)
sudo apt update && sudo apt upgrade nginx
# Apres mise a jour, toujours verifier
sudo apache2ctl configtest && sudo systemctl restart apache2
sudo nginx -t && sudo systemctl restart nginx
reload plutot que restart en production. Le reload recharge la configuration sans interrompre les connexions actives. Le restart coupe toutes les connexions en cours, ce qui peut impacter les utilisateurs.
14. Depannage (logs, configtest)
14.1 Verification de la configuration
# Apache - Tester la syntaxe
sudo apache2ctl configtest
# Resultat attendu : "Syntax OK"
# Apache - Afficher tous les VirtualHosts et leur priorite
sudo apache2ctl -S
# Nginx - Tester la syntaxe
sudo nginx -t
# Resultat attendu : "test is successful"
# Nginx - Afficher la configuration complete resolue
sudo nginx -T
14.2 Emplacements des logs
# === APACHE ===
# Logs par defaut
/var/log/apache2/access.log # Debian/Ubuntu
/var/log/apache2/error.log # Debian/Ubuntu
/var/log/httpd/access_log # CentOS/RHEL
/var/log/httpd/error_log # CentOS/RHEL
# Logs specifiques au VirtualHost
/var/log/apache2/example.com-access.log
/var/log/apache2/example.com-error.log
# === NGINX ===
# Logs par defaut
/var/log/nginx/access.log
/var/log/nginx/error.log
# Logs specifiques au server block
/var/log/nginx/example.com-access.log
/var/log/nginx/example.com-error.log
14.3 Lecture des logs en temps reel
# Suivre les logs d'erreur en temps reel
sudo tail -f /var/log/apache2/error.log
sudo tail -f /var/log/nginx/error.log
# Filtrer les erreurs recentes
sudo tail -100 /var/log/apache2/error.log | grep "error"
sudo tail -100 /var/log/nginx/error.log | grep "error"
# Utiliser journalctl pour les logs systemd
sudo journalctl -u apache2 -f --no-pager
sudo journalctl -u nginx -f --no-pager
# Voir les logs depuis le dernier demarrage
sudo journalctl -u apache2 -b
sudo journalctl -u nginx -b
14.4 Problemes courants et solutions
Port deja utilise
# Identifier le processus qui occupe le port 80 ou 443
sudo ss -tlnp | grep ':80'
sudo ss -tlnp | grep ':443'
# Ou avec lsof
sudo lsof -i :80
sudo lsof -i :443
# Solution : arreter le service concurrent ou changer le port d'ecoute
Permission refusee (403 Forbidden)
# Verifier les permissions du DocumentRoot
ls -la /var/www/example.com/
ls -la /var/www/example.com/public/
# Corriger les permissions
sudo chown -R www-data:www-data /var/www/example.com/ # Apache/Nginx Debian
sudo chown -R nginx:nginx /var/www/example.com/ # Nginx CentOS
sudo find /var/www/example.com/ -type d -exec chmod 755 {} \;
sudo find /var/www/example.com/ -type f -exec chmod 644 {} \;
# Verifier SELinux (CentOS/RHEL)
ls -Z /var/www/example.com/
sudo setsebool -P httpd_can_network_connect 1
sudo chcon -R -t httpd_sys_content_t /var/www/example.com/
502 Bad Gateway (Nginx reverse proxy)
# Verifier que le backend est en cours d'execution
sudo ss -tlnp | grep ':3000'
curl http://127.0.0.1:3000
# Verifier les logs Nginx pour plus de details
sudo tail -20 /var/log/nginx/error.log
# Causes frequentes :
# - Le backend n'est pas demarre
# - Le backend ecoute sur une adresse/port different
# - Timeout du backend (augmenter proxy_read_timeout)
# - PHP-FPM ne tourne pas (pour les sites PHP)
504 Gateway Timeout
# Augmenter les timeouts dans Nginx
location / {
proxy_pass http://127.0.0.1:3000;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
}
# Augmenter les timeouts dans Apache
ProxyTimeout 300
Timeout 300
Certificat SSL expire ou invalide
# Verifier les dates du certificat
sudo openssl x509 -noout -dates -in /etc/letsencrypt/live/example.com/fullchain.pem
# Verifier le certificat en ligne
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates
# Forcer le renouvellement
sudo certbot renew --force-renewal
# Verifier que le certificat configure correspond au domaine
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer
14.5 Outils de diagnostic
# Tester la connectivite HTTP
curl -I http://example.com # En-tetes HTTP uniquement
curl -Lv https://example.com 2>&1 # Verbeux avec suivi des redirections
curl -k https://example.com # Ignorer les erreurs SSL (debug)
# Tester les en-tetes de reponse
curl -sI https://example.com | grep -i "server\|x-\|strict\|content-type"
# Tester un VirtualHost specifique avec un en-tete Host
curl -H "Host: example.com" http://192.168.1.10
# Benchmark basique avec Apache Bench
ab -n 1000 -c 50 https://example.com/
# Verifier les processus Apache/Nginx
ps aux | grep apache2
ps aux | grep nginx
# Verifier la consommation memoire
systemctl status apache2 | grep Memory
systemctl status nginx | grep Memory
14.6 Debug des regles de reecriture
# Apache : activer le log de reecriture
# Dans le VirtualHost (pas dans .htaccess)
LogLevel alert rewrite:trace3
# Nginx : activer le mode debug pour le log d'erreur
# Dans le server block
error_log /var/log/nginx/example.com-error.log debug;
# Attention : le mode debug genere ENORMEMENT de logs
# Desactivez-le immediatement apres le diagnostic
configtest / nginx -t pour valider la syntaxe, 2) consulter les logs d'erreur, 3) verifier les permissions et SELinux, 4) verifier les ports avec ss -tlnp, 5) tester avec curl en local. Cette methode resout 90% des problemes courants.