Nginx, serveur WEB

Un article de Diablotins.org.

(Redirigé depuis Nginx)


Image:brush.png

Nginx, une alternative Ă  Apache.



Comme beaucoup j'ai utilisé Apache comme serveur web.
Même s'il fonctionne très bien, c'est de l'artillerie lourde.
Or, pour mon joli serveur, je n'ai besoin que de :



Nginx est un serveur HTTP léger, un reverse proxy et un serveur proxy IMAP/POP3.
Dans cet article, je ne décrirais que son utilisation en serveur web.

Sommaire

Installation

Nginx est organisé en modules;
chacun apportant une fonctionnalité.

Installez le port “www/nginx-0.5.31_1”. Le Makefile proposant plusieurs options de construction,
nous n'activerons que:

HTTP_MODULE "Enable HTTP module" on
HTTP_REWRITE_MODULE "Enable http_rewrite module" on
HTTP_SSL_MODULE "Enable http_ssl module" on
HTTP_STATUS_MODULE "Enable http_stub_status module" on
WWW "Enable html sample files" on

Le reste étant déasctivé (off).
ceci valide les HTTP (essentiels), la réécriture d'URL (ça peut servir), le SSL sur HTTP et les statistiques.

Une fois le port installé, vous trouverez les fichiers de configuration dans le catalogue “/usr/local/etc/nginx”.
Le port installe un script de démarrage: “/usr/local/etc/rc.d/nginx”.
Évidemment, il faudrait aussi installer “php” et “SquirrelMail”; mais nous n'en causerons pas ici.

Configuration

Éditez “/usr/local/etc/nginx/nginx.conf” pour configurer le serveur; le wiki en fourni quelques exemples ainsi qu'une documentation des directives des modules pour, par exemple, le module “HttpCore”.

Syntaxe

La syntaxe du fichier de configuration n'est pas vraiment documentée (du moins en anglais) et ce qui suit n'est qu'une déduction.

Le fichier de configuration est organisé en “contextes”, ouverts par une accolade gauche, “{”
et fermés par une accolade droite, “}”.
Un contexte contient des directives, qui peuvent aussi ĂŞtre un contexte. Ces directives ne s'appliquent qu'au contexte courant et Ă  ses sous-contextes. Pour chaque directive, la documentation indique quel est le contexte attendu.

Dans l'exemple ci-dessous, le contexte “http” inclue un contexte “server” qui inclue lui-même un contexte “location”.

   http {
       directive
       directive
       directive
       server {
            directive
            location xxxx {
                directive
            }
       }
   }

D'une manière générale, ce fichier est composé d'un contexte principal, suivi d'un contexte “http” qui inclue un contexte “server” pour chaque serveur HTTP.

Contexte principal

Ce contexte donne les directives qui concernent le démon lui-même.
i.e. l'utilisateur et le groupe utilisé par Nginx, le nombre de processus “worker” etc.

   user  www www;
   worker_processes  1;
   events {
      worker_connections  1024;
   }

Contexte HTTP

Ce contexte défini les directives communes à tous nos serveurs, soit chaque contexte server.

 http {
   # types MIME : voir /usr/local/etc/nginx/mime.types
   include       mime.types;
   default_type  application/octet-stream;
   # utilise sendfile
   sendfile        on;
   # autoindex 
   autoindex on;
   autoindex_exact_size off;
   # Taille maximale du corps d'une requĂŞte client.
   # Il est indispensable de l'augmenter pour pouvoir
   # échanger des fichiers importants (pièces jointes)
   # avec SquirellMail
   client_max_body_size 7m;

Contexte server

Ce dernier(Standard HTTP Modules) est la partie qui va le plus nous intéresser, chaque contexte décrit un serveur HTTP.

Soit un serveur nommé “lamaiziere.net” ou www.lamaiziere situé dans le catalogue “/home/www/lamaiziere.net”, les fichiers php étant transmis en FastCGI pour être exécutés.

server {
  # port d'Ă©coute (80 Ă©tonnant non ?)
  listen  80;
  # noms du serveur, le serveur s'appelle lamaiziere.net
  # ou www.lamaiziere.net
  server_name  lamaiziere.net www.lamaiziere.net;
  # chemin de la racine du serveur et fichiers d'index
  location / {
    root   /home/www/lamaiziere.net;
    index  index.html index.htm index.php;
  }
  # redirige les pages d'erreurs vers les pages statiques /50x.html
  #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   html;
    }
  # Transfère les scripts PHP au serveur FastCGI qui écoute sur
  # 127.0.0.1, port 8002
  # voir la partie sur le PHP
  location ~ \.php$ {
    fastcgi_pass   localhost:8002;
    fastcgi_index  index.php;
    fastcgi_param SCRIPT_FILENAME  /home/www/lamaiziere.net$fastcgi_script_name;
    include        fastcgi_params;
  }
}

Si on veut cloner www.lamaiziere.net en HTTPS (ssl), il suffit d'un copier coller du serveur précédent, de le faire écouter sur le port 443 et d'y ajouter les directives pour le SSL.
Et bien sûr de créer les certificats.

Important : Du fait que SSL est utilisĂ© dès la connexion au serveur, il n'est pas possible de spĂ©cifier un certificat par hĂ´te virtuel. Nginx utilise le premier certificat spĂ©cifiĂ© dans un contexte server sur le port 443. Les directives ssl devraient plutĂ´t ĂŞtre spĂ©cifiĂ©es au niveau d'un contexte supĂ©rieur (bug de Nginx ?).

Ce qui donne :

 server {
   listen  443;
   server_name  lamaiziere.net www.lamaiziere.net;
   ssl                  on;
   ssl_certificate      /usr/local/etc/nginx/server.crt;
   ssl_certificate_key  /usr/local/etc/nginx/server.key;
   ssl_session_timeout  5m;
   ssl_protocols  SSLv2 SSLv3 TLSv1;
   ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
   ssl_prefer_server_ciphers   on;
   [...CUT...]

Et c'est tout ! On peut ajouter des serveurs virtuels simplement en ajoutant des directives “server”, par exemple «http://jpm.lamaiziere.net»:

server {
  listen  80;
  # nom du serveur, le serveur s'appelle jpm.lamaiziere.net
  server_name  jpm.lamaiziere.net
  # chemin de la racine du serveur et fichiers d'index
  location / {
    root   /home/www/jpm;
    index  index.html index.htm;
  }
  [...CUT...]
}

PHP

Nginx passe les scripts php à exécuter en FastCGIà PHP qui doit donc être compilé avec l'option FASTCGI du port “lang/php5”.

[X] FASTCGI    Enable fastcgi support (CGI only)

Php doit aussi être lancé en mode serveur;
pour cela il y a deux mĂ©thodes : utiliser le programme spawn-fcgi qui vient avec le serveur “lighttpd”, (port “www/lighttpd”) ou faire un script qui va lancer PHP. Voir http://blog.kovyrin.net/2006/05/30/nginx-php-fastcgi-howto/.

Pour ma part j'utilise le script rc suivant :

 
#!/bin/sh
 
# PROVIDE: phpcgi
# REQUIRE: DAEMON
# BEFORE: LOGIN
# KEYWORD: shutdown
 
# Define these phpcgi_* variables in one of these files:
#       /etc/rc.conf
#       /etc/rc.conf.local
#
# DO NOT CHANGE THESE DEFAULT VALUES HERE
#
phpcgi_enable=${phpcgi_enable-"NO"}
phpcgi_flags=${phpcgi_flags-""}
phpcgi_user=${phpcgi_user-"www"}
phpcgi_child=${phpcgi_child-"5"}
phpcgi_maxrequests=${phpcgi_maxrequests-"500"}
phpcgi_pidfile=""
 
. /etc/rc.subr
 
name="phpcgi"
rcvar=`set_rcvar`
command="/usr/local/bin/php-cgi"
procname="php-cgi"
 
load_rc_config $name
 
PHP_FCGI_CHILDREN=${phpcgi_child}
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=${phpcgi_maxrequests}
export PHP_FCGI_MAX_REQUESTS
 
start_cmd="echo \"Starting ${name}.\"; /usr/bin/su -m ${phpcgi_user} -c \"${command} ${phpcgi_flags} &\""
stop_cmd="echo \"Stopping ${name}.\"; /usr/bin/killall ${procname}"
 
run_rc_command "$1"

php-cgi ne renvoie pas le pid du processus créé d'où le killall qui ne me plaît pas trop, si vous avez une idée n'hésitez pas. Configurez le tout au démarrage, par /etc/rc.conf:

phpcgi_enable="YES"
# adresse et port d'écoute (qui doit correspondre
# avec la conf de Nginx!)
phpcgi_flags="-b localhost:8002 -q"
# utilisateur
phpcgi_user="www"
# nombre de processus fils
phpcgi_child="5"
# nombre de requĂŞtes max par fils, au bout de ce nombre
# le processus fils est arrêté et un nouveau est créé.
phpcgi_maxrequests="100"

Conclusion

Nginx fonctionne bien, je n'ai pas eu le moindre soucis pour l'instant. Léger et facile à configurer il peut être une alternative intéressante à Apache.

En savoir plus

Chanson

Ivan and Aljosha, Pavel and Serjosha,
Leonid and Vladimir, Juri and Grigori
Those Russian boys they sing so nice
Juchei Juchei Kalinka Kalinka Kalinka...
[Nina Hagen - Russian Reggae]

Projets :
Boîte à outils