Nginx

Installer Nginx avec php-fpm

Vous qui avez l’habitude de fonctionner avec Apache, vous allez voir une alternative intéressante avec Nginx, qui peut à la différence de Apache jouer plusieurs rôles, reverse proxy, load balancer, mise en cache.

Nous allons partir d’une image docker debian de base officielle

docker pull debian
docker run -it debian

Nous aurions pu faire un dockerfile pour installer les packages nécessaire mais nous allons essayer de faire une configuration minimaliste, sans systemd ni supervisor.

Installation des packages

nous aurons besoin de curl nginx vim php-fpm etc (on découvrira au fur et à mesure)

apt update
apt install nginx php-fpm curl vim

configuration du fichier vhost de phpsite

Ce fichier est à placer dans le répertoire /etc/nginx/sites-available/

server {
    listen 80;
    server_name phpsite;

    root /var/www/phpsite;
    index index.php index.html;

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass 127.0.0.1:9000;
}

la ligne include fastcgi_params est important, car permet à Nginx d’exécuter le PHP, sinon un curl vous renvoit le texte du code.

La ligne fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Vous testez ce script avec la commande nginx -t qui vérifiera s’il n’y a pas d’erreur.

Pour rendre ce site actif il faut créer un lien symbolic dans le répertoire /etc/nginx/sites-enabled/ qui pointe vers ce fichiers de configuration de vhsot qu’on appelera phpsite.conf

sudo ln -s /etc/nginx/sites-available/phpsite.conf /etc/nginx/sites-enabled/phpsite.conf

Le fichier php info.php

cd /var/www/phpsite
touch info.php
nano info.php

<?php 
echo "Hello";
?>

Vous devez démarrer php-fpm pour prendre en charge l’exécution du php et démarrer nginx aussi

Démarrage des services pour accéder à un site en php

Démarrage de php-fpm

le fait qu’on n’utilise pas systemd ni supervisor nécessite qu’on démarre à la main php-fpm et utiliser le socket TCP et non le socket Unix

 /usr/sbin/php-fpm8.2 -F

le -F fait démarrer php-fpm en foreground.

Démarrage de Nginx

nginx -g "daemon off;"

Cette commande évite de démarrer nginx en tâche de fond, comme ça on a les logs si jamais il y a une erreur.

Erreurs et problèmes possibles

Si vous essayez d’atteindre une page php avec curl

curl http://phpsite/info.php

// n'oubliez pas d'ajouter dans le fichier /etc/hosts/ le vhost phpsite
vim /etc/hosts

// contenu du fichier

et que vous avez un erreur 502 Bad Gateway, c’est que php-fpm écoute sur un socket Unix et que Nginx est paramétré sur un socket TCP. Pour savoir quel type de configuration a php-fpm:

// commande pour savoir quel type de socket php-fpm utilise
grep -E "^listen" /etc/php/8.2/fpm/pool.d/www.conf

//Dans le fichier /etc/php/8.2/fpm/pool.d/www.conf, remplacez le socket Unix par le socket TCP.
listen = /run/php/php8.2-fpm.sock  # socket Unix
listen = 127.0.0.1:9000    # socket TCP

Dans notre cas (fonctionnement sans systemd et supervisor, on va choisir les socket TCP.)

On va donc changer la configuration de php-fpm

vim /etc/php/8.2/fpm/pool.d/www.conf 
on cherche la ligne où on a 
listen = /run/php/php8.2-fpm.sock 
pour remplacer par
listen = 127.0.0.1:9000

et on redémarre php-fpm et nginx 

PHP ne s’exécute pas mais affiche le code à la place, Nginx n’arrive pas à communiquer avec php-fpm. Vérifiez que ce dernier soit bien démarré.

cela veut dire que le fichier est traité comme un fichier texte, vérifiez que vous avez inclus

Note : Créer une nouvelle image avec ces modifications

Créer une image avec toutes ces modifications, afin de ne pas avoir à refaire les manipulations, en somme préparer une image pour un usage.

Quittez tous les process à l’intérieur du docker, quittez le docker et vérifiez que le process docker en question est stoppé avec docker ps. Ensuite on va commiter le docker avec son id selon la syntaxe suivante:

docker ps -a // pour voir l'id du container 

docker commit <nom_ou_id_du_conteneur> monimage:1.0

docker commit b425 monimage:1.0

Sauver l’image docker dans le repository distant (hub de docker)

Ensuite vous devez sauver cete image dans un repository, le plus commun est le hub de docker.com

// connexion avec le hub
docker login

// tagging de l'image avant de pouvoir l'envoyer dans le repository
docker tag debian-nginx refschool/debian-nginx:1.0
^ debian-nginx est l'image qu'on vient de créer
// push de l'image docker
docker push refschool/debian-nginx:1.0

Rappel de commandes Nginx sans Systemd et sans supervisor

  • démarrer en avant plan : nginx -g « daemon off »; »
  • test du fichier de configuration : nginx -t
  • arrêt : nginx -s stop
  • arrêt graceful : nginx -s quit (nginx arrête les connexions avant de s’arrêter
  • redémarrer : nginx -s reload
  • savoir si nginx tourne : ps aux | grep nginx

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

Configuration Nginx comme load balancer

ON a vu comment mettre Nginx en reverse proxy, nous aller plus loin en configurant un load balancer

Qu’est ce qu’un load balancer?

Un load balancer permet de répartir la charge d’un site web sur plusieurs serveur qui tournent indépendamment. Un serveur web qui reçoit beaucoup de visite aura tendance à ralentir, ce n’est pas la résolution de la ressource qui est lente, car l’opération demande peu de ressource, mais le travail du serveur pour calculer la page web. D’où l’idée de monter plusieurs serveurs et de monter un reverse proxy qui va être le premier à intercepter la requête et à la rediriger vers un des serveurs.

Installation de Nginx

sudo apt install -y nginx

Fichier de configuration de Nginx

Le fichier de configuration se trouve dans /etc/nginx/nginx.conf

server {

listen 80;
server_name   myserver;

location /static {
    root /var/www/myserver;

}

location / {
    proxy_pass  http://localhost:8000;
    proxy_http_version. 1.1;
    proxy_set_header X-Forwarder-Host $server_name;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

}

}

Modification du fichier de configuration pour indiquer les 3 hôtes

log_format upstreamlog '$server_name to: $upstream_addr [$request] '
    'upstream_response_time $upstream_response_time'
    'msec $msec

upstream serveurs {
    server http://localhost:8000;
    server http://localhost:8001;
    server http://localhost:8002;

}


server {

    listen 80;
    server_name   myserver;
    access_log    /var/log/nginx/access.log  upstreamlog;

location /static {
    root /var/www/myserver;

}

location / {
    proxy_pass  http://serveurs;
    proxy_http_version 1.1;
    proxy_set_header X-Forwarder-Host $server_name;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";

}

}

Dry run ou lancement d’essai pour vérifier que le script n’est pas en erreur

sudo nginx -t 

// pas d'erreur normalement


sudo systemctl reload nginx


sudo tail -f /var/www/nginx/access_log

Maintenant dans votre navigateur, allez à l’adresse http://myserver, et rechargez plusieurs fois. Regardez les logs, on doit voir les 3 port du localhost utilisés.

La stratégie round robin

Avec cette stratégie, le reverse proxy distribue à tout le monde équitablement, chacun son tour.

On va faire une application NodeJS qu’on va lancer trois fois avec des ports différents


		

Installer NginX en tant que reverse proxy

C’est quoi Nginx?

Nginx est un serveur web de contenu statique. Mais il a d’autres fonctionnalités qui font son attrait, et parmi les plus souvent cités, le reverse proxy.

On a vu comment installer Nginx en tant que serveur web, mais on va faire du reverse proxy dans cet article.

C’est quoi un reverse proxy?

Habituellement que vous sollicitez une page web, votre navigateur va directement tutoyer le serveur Apache par exemple ou NodeJs. Par contre si vous mettez un reverse proxy, c’est le reverse proxy qui va être sollicité en premier, et passer la requête ensuite au serveur Apache. Il agit comme un intermédiaire.

Source Wikipedia

Pourquoi s’embête-t-on à mettre un intermédiaire entre le serveur et le navigateur? L’utilité la plus évidente est que c’est une solution pour exposer votre serveur NodeJS qui fonctionne sur le port 3000, ou votre serveur Python, tout en montrant au monde extérieur un port 80, qui est celui par défaut du Web.

Installation de Nginx

Pour faire ce tuto je vais utiliser digitalOcean, une Paas, très pratique et peu cher, à condition de détruire votre instance après usage, bref, pour apprendre le cloud et Docker par exemple c’est idéal.

Je vais créer un droplet Ubuntu avec autenthification par clé SSH, pour éviter d’avoir à me connecter à chaque fois que je vais en mode console.

sudo apt update

sudo apt install nginx

nginx -v

cette commande sert en fait à tester si nginx est bien installé (en plus d'avoir sa version)

Maintenant on va pouvoir démarrer Nginx.

sudo systemctl start nginx

Pour que Nginx puisse démmarer automatiquement au reboot, vous devriez le redémarrer avec la command esuivante :

sudo systemctl enable nginx

# pour checker l'état de Nginx
sudo systemctl status nginx
#il doit mentionner active

Casser le lien avec le fichier de configuration d’origine.

Comme nous allons utiliser Nginx en mode reverse proxy, nous allons casser le lien avec l’encien fichier de configuration et en établir un nouveau.

sudo unlink /etc/nginx/sites-enabled/default

# création d'un nouveau fichier de configuration
sudo vim /etc/nginx/sites-available/reverse-proxy

avec le contenu cidessous dans ce fichier:


server {
    listen 80;
    server_name localhost;
    location / {
        proxy_pass http://127.0.0.1:8000;
        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;
    }
}

La configuration consiste en un bloc server {…} qui gère toutes les requêtes correspondant aux conditions spécifiées. Il contient les éléments suivants :

listen 80 : Le serveur écoute les requêtes HTTP entrantes sur le port 80.
server_name localhost : Le nom de domaine pour lequel ce bloc serveur est responsable. L’exemple utilise localhost pour illustrer le fonctionnement du reverse proxy .
location / {…} : La configuration pour le chemin d’URI spécifié. Ici, il correspond à toutes les requêtes (/).
proxy_pass http://127.0.0.1:8000 : Le serveur backend vers lequel NGINX redirige les requêtes. L’exemple utilise l’adresse locale sur le port 8000 (127.0.0.1:8000) comme backend de substitution. Dans un cas réel, utilisez l’URL du serveur backend approprié.
proxy_set_header : La directive permettant de définir des en-têtes HTTP pour la requête proxy. Ces en-têtes sont transmis au serveur backend et fournissent des informations supplémentaires sur la requête du client. L’exemple inclut l’en-tête Host, l’adresse IP du client et le schéma (HTTP ou HTTPS).
Remplacez le numéro de port, le nom du serveur et l’adresse du serveur backend par les données réelles. Cet exemple redirige toutes les requêtes faites à localhost vers l’adresse http://127.0.0.1:8000.

Lier le nouveau fichier de configuration

sudo ln -s /etc/nginx/sites-available/reverse-proxy /etc/nginx/sites-enabled/

#test nginx
sudo nginx -t

#redémarre Nginx
sudo systemctl restart nginx

Tester le reverse proxy, exemple avec Python

Créer un répertoire, faire un fichier index.html, et lancer le serveur web Python depuis ce même répertoire. Par exemple /var/www

<html>
<head>
  <title>NGINX backend</title>
</head>
<body>
  <h1>ça marche !</h1>
</body>
</html>

#lancer le serveur

python3 -m http.server 8000

Il se peut que Python ne soit pas installé, pour Debian faites : sudo apt install python3

Test avec Curl de cette page et accès à cette même page par un navigateur.

curl http://14.35.123.45/index.html

Cas d’une application NodeJS sur le port 3000

On applique la même stratégie, on modifie le fichier pour remplacer le port 8000 par 3000.

Explication reverse proxy avec Nginx en vidéo

nginx

Installer NGINX sous Windows 10

NGINX est le second serveur web qui propulse les sites en PHP. Il se veut plus rapide qu’Apache, mais il est surtout fait pour servir du contenu statique. Cependant, sa conception le rend intéressant pour installer plusieurs version de PHP en simultané. Notez que Apache est également capable de le faire, mais ce petit tuto est là pour vous montrer une façon de faire sous Windows.

Téléchargez NGINX

Pour ce faire allez sur le site officiel sur cette page de et suivez les instructions (téléchargez la mainline). Nous prenons ici le parti de tout faire et de ne pas installer un équivalent de WAMP pour NGINX. (http://nginx.org/en/docs/windows.html)

Décompressez l’exécutable où vous voulez, démarrer le serveur équivaut à démarrer un programme quelconque (NGINX ne tourne pas comme un service Windows, c’est écrit sur la page).

Démarrer Nginx

allez dans le répertoire de votre nginx et tapez la commande
>start nginx
 ensuite pour visualiser les process

>>tasklist /fi "imagename eq nginx.exe"

Nom de l’image                 PID Nom de la sessio Numéro de s Utilisation
========================= ======== ================ =========== ============
nginx.exe                    15308 Console                   17     8 260 Ko
nginx.exe                    15476 Console                   17     8 588 Ko

Une fois que vous avez démarré l’exécutable, prenez connaissance de ces quelques commandes :

nginx -s stop 	fast shutdown
nginx -s quit 	graceful shutdown
nginx -s reload 	changing configuration, starting new worker processes with a new configuration, graceful shutdown of old worker processes
nginx -s reopen 	re-opening log files

Notez que ces commandes n’ont pas l’air de marcher sous Windows 10, ça ne marche que si vous êtes dans le même répertoire que l’exécutable nginx.exe. Cependant voici la commande qui tuera pour sûr les process partout :

taskkill /f /IM nginx.exe

Télécharger le zip PHP

Sur le site officiel, dans la section windows, Télécharger un package PHP 7.4, choisissez le thread safe 64bits si vous êtes sous Windows 10 (je suppose qu’en 2020, vous êtes dans ce cas)

Décompressez le zip dans un répertoire c:\PHP\7.4

constituez un fichier .bat pour lancer le fichier C:\PHP\7.4\php-cgi.exe, s’assurer que cet exécutable est dans le même répertoire que le php.exe.

@ECHO OFF
ECHO Starting PHP FastCGI...
set PATH=C:\PHP;%PATH%
rem c:\bin\RunHiddenConsole.exe 
C:\PHP\7.4\php-cgi.exe -b 127.0.0.1:9123

De même si vous voulez arrêter le process de Fast CGI voici la commande :

taskkill /f /IM php-cgi.exe

Ensuite dans le fichier de configuration de NGINX nginx.conf dans la section server, ajoutez la ligne include fast-cgi.conf :

server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9123;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi_params;
            include fastcgi.conf;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

Si vous n’avez pas cette ligne vous aurez un message « No input file specified ».

Démarrer le serveur NGINX avec le PHP Fast CGI

Démarrez le fichier batch, ensuite démarrez NGINX, allez dans le dossier c:\nginx\html (créez un fichier index.php), dans le navigateur allez à http://localhost, votre page doit normalement s’afficher. Prochain article nous verrson comment affecter une version de PHP par virtual host.

Connaitre les variables de configuration du cache de Nginx

Je passe un peu en revue les directives utilisées dans le fichier de configuration du cache.

Nginx utilisé en reverse proxy sans le caching des pages ne rime à rien. On l’utilise pour servir du contenu statique afin d’accélérer grandement le temps de téléchargement, et croyez moi il est plutôt performant !

Un serveur proxy se met entre l’internaute et le serveur Apache par exemple (mais ça peut être n’importe quel serveur).

 

 

Directive Signification
proxy_cache définit une zone mémoire partagée pour stocker le cache
proxy_cache_bypass
proxy_cache_key  une valeur de type string, utilisée pour classer les parties du cache
proxy_cache_lock  si plusieurs requêtes demandent une page non cachée, la première crée le contenu caché avant que les autres puissent lire le cache évitant à toutes les requêtes de demander du contenu dynamique
proxy_cache_lock_timeout
proxy_cache_min_uses  nombre de fois qu’un contenu demandé avant d’être caché
proxy_cache_path  répertoire ou sera placé le contenu caché, on y place les clé (qui identifie les pages cachées) et le métadonnées
proxy_cache_use_stale  définit le cas de figure où l’on sert du contenu caché lorsque l’appel au serveur du backend (Apache) donne une erreur
proxy_cache_valid durée du vie du cache (la page web doit retourner 200,301 ou 301), ici cela veut dire que les page retournant un code cité ci-dessus sera caché, les pages 404 par exemple ne sont pas cachée

Installation de Nginx en front end Apache en backend

Aujourd’hui le moteur de recherche Google veut faire de la vitesse de chargement d’un site web un critère de ranking dans les SERPs.

Ce n’est pas idiot, et de toute façon, sans même parler de moteur de recherche, il est important d’avoir un site web qui va vite.

Dans le domaine du e-commerce par exemple, il ne faut pas que la vitesse de chargement dépasse 4 secondes.(les puriste disent 2), mais on va dire 3 (coupons la poire en deux) c’est ok.

Le problème est quand le site de e-commerce devient grand, quand il y a beaucoup de gens qui visitent le site (forcément vous avez un site qui marche sinon), et de même il n’y a pas que des humains qui vous rendent visite il y a aussi les spiders !

Entre Google bot qui passe toutes les minutes ou toutes les 10 secondes, les bots de majesticSEO ou de Ahrefs, archive.org etc, votre Apache hé bien il est surchargé.

Vous aurez beau optimiser les facteurs suivants : compression GZIP, mise en place d’un cache, utilisation de serveur de médias, de CDN, de minification des scripts, de mise en place de javascript à la fin, ces solution ont une limite à la fin, cela ne suffira pas.

La solution ultime c’est NGINX !

C’est quoi Nginx? c’est un serveur web comme Apache, écrit par un Russe, il est plutôt peu gourmand en ressource, et il est rapide pour servir des fichiers statique. Statique? vous dites Cache? hé bien c’est pas loin !

Le secret ici est de servir tout ce qui est statique par NGINX et ce qui est dynamique par Apache.

Nginx est dans ce cas ce qu’on appelle un reverse proxy, ou serveur frontal. Définition sur cette page.

Donc avec Nginx on peut faire ces 5 choses :

  1. servir du contenu statique
  2. intermédiaire de sécurité
  3. terminal SSL
  4. répartition de charge (load balancing)
  5. compression de site

Nous allons donc dans les lignes qui suivent, installer Nginx sur un serveur dédié qui tourne déjà avec le serveur web Apache, ils seront donc sur la même machine.

 

Installation de Nginx en ligne de commande (Linux Debian)

Là je suppose que vous avez des connaissance en shell, c’est très simple, il faut installer Nginx avec la commande suivante :

$ apt-get install nginx

il faut que vous vous loggiez en root pour faire marcher cette commande.

Une fois que Nginx est installé, il y a déjà un fichier de configuration example. Sauvegardez ce fichier sur votre ordinateur pour le réutiliser si besoin, mais on n’aura pas besoin, cependant renommez ce fichier au nom de votre site web. J’utilise Winscp pour manipuler de manière sécurisée les fichiers depuis mon ordinateur en effet le faire en ligne de commande est assez fastidieux.

Configuration d’un fichier serveur Nginx

Le fichier de configuration de site web de Nginx doit être installé dans le répertoire (pour les Debian) , comme pour Apache 2, dans sites-available et sites-enabled.

« Available » veut disponible et « enable » veut dire activé. En fait si vous avez un fichier dans « enabled », ça veut dire que le site est en ligne.

Le fichier dans sites-enabled est un lien symbolique vers le fichier de configuration du répertoire site-available.

Nginx en ce qui concerne les webmasters a deux fonctions bien distinctes, soit vous l’utilisez pour remplacer Apache (ce dernier est donc à virer) soit vous l’utiliser comme reverse proxy (thème de cet article), donc il fonctionnera parallèlement à Apache !

Notion fondamentale : Si Nginx et Apache fonctionnement en même temps, pour éviter tout conflit, Apache qui écoute habituellement sur le port 80 doit changer de port, on le mettre sur le port 8080, et Nginx sur le port 80, ce qui suppose une modification du fichier de configuration d’Apache comme on le verra plus tard dans cet article.

Imaginons que je veuille proxier phpninja.fr

server {

  listen   80; ## listen for ipv4

  server_name  phpninja.fr www.phpninja.fr;
  access_log  /var/log/nginx/localhost.access.log;

  location / {
    root   /home/phpninja.fr/public_html/;
    index index.php index.html index.htm;
    try_files $uri $uri/ /index.php;
  }


  # proxy the PHP scripts to Apache listening on 127.0.0.1:8080
  #
  location ~ \.php$ {

  proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;

  proxy_set_header Host $host;
  proxy_pass   http://88.191.158.109:8080;
  }



  # deny access to .htaccess files, if Apache's document root
  # concurs with nginx's one
  #
  location ~ /\.ht {
    deny  all;
  }
}

Listen 80 : on dit à nginx d'écouter sur le port 80

Server name : on donne les sites à proxier

Un fichier de log est spécifié, utile quand vous voulez débugger.

Dans Location /, vous lui dites où se trouve la racine du site web, le fichier index, et try files sert à dire à Nginx de proxier toutes les requêtes, si Nginx ne peut pas, alors il va passer le requête à Apache.

Location ~ \.php$  est trè_s important, il dit qu’il faut passer les fichier php à Apache. Comme dit plus haut Nginx ne vient pas avec le support de php, donc il est logique que ce soit Apache qui le fasse.

 

Proxy pass indique l’adresse IP du serveur auquel les requêtes sont passée (adresse IP de votre virtual host Apache).

 

Enfin location ~ /\.ht sert à éviter tout conflit dans l’interprétation du fichier type htaccess, ht_password etc dans le cas ou Nginx et Apache en ont.

Modification de la partie Apache

Il faut maintenant qu’Apache écoute sur le port 8080, c’est la seule modification que vous aurez à faire. Dans le cas de Debian, il faut modifier le fichier ports.conf comme suit:

Listen 88.191.158.109:8080
Listen 443

Il faut aussi modifier NameVirtualHost

NameVirtualHost 88.191.158.109:8080

Faire la manip sur tous les fichiers Vhost même si vous ne voulez pas les proxier. Dans tous les cas il faut le faire car Apache doit écouter sur 8080 au lieu de 80, sinon le démarrage de Nginx sera problématique.

ensuite il faut installer le module rpaf.

Il sert à envoyer à Apache l’IP du navigateur et non celui de Nginx, sinon vous perdrez cette information.

RPAFenable On
RPAFsethostname On
RPAFproxy_ips 213.246.45.34

spécifier l’adresse publique du proxy.

Conclusion

Redémarrer Apache et Nginx avec les commandes :

service apache2 restart
service nginx restart

Si tout se passe bien, vous allez voir une accélération de votre site ! Et encore on n’a pas encore fait les optimisations de Nginx !

Pour vous amuser, vous pouvez mettre un fichier info.php avec l’instruction phpinfo().

Dans la page qui s’affichera, vous verrez la signature de Apache.

Par contre si vous avez Firebug, ou Httpfox, vous verrez la réponse du serveur le nom Nginx.

Retour en haut