Mettre en place un Reverse Proxy Nginx sur son serveur

par Korben -

A cause (ou grâce) au petit concours que j’ai lancé pour gagner le Nokia N900, vous êtes trèèèèèèès nombreux à être sur le site, à laisser un commentaire puis après aller vous ballader sur mes autres articles. C’est bien (yeah!) sauf que du coup l’Apache qui fait tourner le site a eu un peu de mal à gérer l’affluence.

J’ai donc du mettre en place un petit serveur Nginx pour faire office de Reverse Proxy afin d’alleger le tout. Je ne me prétend pas expert en nginx mais je vais tenter de vous expliquer avec mes mots (c’est à dire simplement) comment mettre ça en place chez vous.

Mais avant ça, petit cours de comment fonctionne un serveur http classique type Apache !

Lorsque vous arrivez avec votre petit navigateur sur Korben.info (qui tourne sous wordpress), voici ce qui se passe :

  • Votre ordinateur envoie une demande de connexion au serveur Apache
  • Votre navigateur peut alors se connecter au serveur Apache
  • Apache crée alors un nouveau process pour gérer votre demande
  • Si c’est du contenu statique que vous demandez (genre une image), Apache va la chercher et vous l’envoie (facile)
  • Mais si c’est du contenu dynamique (genre page en PHP), Apache la demande et doit attendre que PHP (souvent en appelant un petit coup MySQL dans la foulée) ai fini de générer cette page pour vous la renvoyer.
  • Votre navigateur reçoit alors le fichier demandé, il ferme la connexion avec l’Apache et vous affiche le contenu demandé

Great !

Sauf que ce qu’on ne vous dit pas, c’est qu’en cas de nombreuses demandes, votre Apache il souffre sa race ! En effet, il peut en quelques minutes bouffer toute la mémoire de votre serveur et faire tourner le CPU à plus de 100 % ! Pas cool ! Une des solutions consisterait donc à acheter un plus gros serveur mais avant de sortir le chéquier, il est possible de l’optimiser encore un petit peu.

On peut en effet confier la distribution des fichiers statiques à un serveur comme Nginx qui a l’avantage d’être très rapide pour exécuter cette tâche. La mémoire vive consommée par Nginx est très réduite, ce qui permet de le charger un peu sans exploser la mémoire. Ayant déjà une architecture Apache en place, je ne voulais pas passer ma nuit à tout migrer sur Nginx en tant que serveur web (et surtout ne pas me prendre la tête avec les reécriture d’URL qui se gère un peu différemment sous Nginx). J’ai donc décider de l’utiliser comme un Reverse Proxy. C’est à dire de faire tourner l’Apache (avec le blog et tout et tout) sur un autre port uniquement en local sur mon serveur et de demander à Nginx de s’occuper de la distribution de contenu pour vous mes fidèles visiteurs :-)

Au niveau du contenu statique, j’ai un sous domaine korben.info qui diffuse uniquement les images du site. J’ai donc choisi de faire distribuer ces fichiers directement par le Nginx plutôt que par Apache. Autre avantages de Nginx, c’est qu’il gère le loadbalancing, ce qui sera pratique quand je commencerai à faire plus de trafic que Facebook… (ouais j’y crois !!!)

Voici au final à quoi ressemble la config que j’ai mis en place :

Z’avez vu ? Je fais des beaux schémas ! C’est grâce à Pencil qui est sorti en 1.1 RC1 (ça c’était la news dans la news !!)

Bref, trêve de blabla, si vous êtes chaud, on attaque !

Avant tout, vous allez stopper votre Apache (sudo /etc/init.d/apache2 stop). Puis on va installer Nginx

sudo apt-get install nginx

Ensuite, on va éditer le fichier /etc/nginx/nginx.conf Voici ce que j’ai mis dans le mien :

 user www-data; worker_processes 2; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; server_names_hash_bucket_size 64; sendfile on; tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; tcp_nodelay on; gzip on; gzip_comp_level 5; gzip_http_version 1.0; gzip_min_length 0; gzip_types text/plain text/html text/css image/x-icon application/x-javascript; gzip_vary on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } 

worker_processes à 2, c’est pour indiquer le nombre d’instance de Nginx que je souhaite lancer pour traiter tout ce business… J’ai mis à 2 pour voir et je réduirai / augmenterai après mes tests. worker_connections à 1024, cela veut dire que chaque process est capable d’encaisse 1024 connexions simultannées (pas visiteurs hein, connexions !). Pour le reste, je vous invite à lire la doc mais globalement, j’ai activé la compression gzip pour que ça booste encore un peu plus et j’ai laissé le timeout à 65 secondes.

A la fin, vous pouvez voir que j’apelle tous les .conf dans /conf.d/ et tous les /sites-enabled/ On va donc aller éditer ces fichiers. Commençons par /conf.d/proxy.conf. Voici ce qu’il faut mettre dedans pour qu’il fonctionne comme un proxy. Idem pour la doc si vous voulez en savoir plus sur les paramètres mais globalement, vous pouvez régler ici les tailles de buffers pour gérer les entêtes et corps envoyés par les clients afin de pouvoir par exemple récuperer des gros cookies ou ce genre de choses (de ce que j’ai pu comprendre).

 proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; client_header_buffer_size 64k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 16k; proxy_buffers 32 16k; proxy_busy_buffers_size 64k; 

Et pour finir, dans site-enabled, un peu comme dans la config Apache, j’ai édité le fichier default dans lequel j’ai mis les choses suivantes (mes commentaires sont dans le code ci-dessous) :

 #PREMIERE CONFIG : Ici je dit que sur le port 80, pour le domaine #korben.info, nginx va chercher les pages en local (127.0.0.1) #sur l'Apache qui est configuré en port 8080 server { listen 80; server_name korben.info; access_log /var/log/korben.access.log; error_log /var/log/korben.nginx_error.log debug; location / { proxy_pass http://127.0.0.1:8080/; } #Et je rajoute PHPMYADMIN dans la foulée location /phpmyadmin { proxy_pass http://127.0.0.1:8080/phpmyadmin; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www/nginx-default; } } #SECONDE CONFIG : Ici je dit que sur le port 80, tout ce qui est #pour le domaine korben.info doit être envoyé directement #par le Nginx et se trouve dans le repertoire /var/www/monsite/wp-content/uploads/ server { listen 80; server_name korben.info; location = /50x.html { root /var/www/nginx-default; } access_log /var/log/pictures.nginx.access.log; error_log /var/log/picture.nginx.error.log; index index.html; location / { expires max; root /var/www/monsite/wp-content/uploads/; } } 

Ayé, on a fait le plus dur. Maintenant, on va configurer l’Apache pour qu’il cause sur le port 8080 uniquement. Voici ce que j’ai mis dans le fichier /etc/apache2/ports.conf

NameVirtualHost * Listen 127.0.0.1:8080 

Et dans mes site-enabled Apache, j’ai bien mis en début de fichier afin d’indiquer une nouvelle fois (on n’est jamais trop prudent) que tout se passe sur le port 8080. Dernière petite chose. Pour que l’Apache logue correctement les IPs qui se connectent à votre serveur, il faut installer le module suivant :

sudo apt-get install libapache2-mod-rpaf

Et voilà ! Il ne reste plus qu’à démarrer l’Apache sur son nouveau port, et le Nginx sur le port 80.

  • sudo /etc/init.d/apache2 start
  • sudo /etc/init.d/nginx restart (ou reload ou start)

Allez ensuite sur votre site et si ça ne fonctionne pas c’est que vous vous êtes planté quelque part dans la config. En cas d’abandon de votre part, il suffit tout simplement de shooter le nginx et de remettre l’Apache sur le port 80 et ça sera reparti comme en 40 ! :-) Si vous souhaitez apporter des corrections / précisions à ce petit tuto, n’hésitez pas !

A vous la toute puissance de l’internet rapide, le succès avec les femmes et un meilleurs référencement (oui car Google tient compte maintenant du critère de vitesse dans le référencement des sites)

Love !