[Summer Camp] Étape 1 – Frontaux Web (Nginx + PHP5)

7 August 2011 | par | tuto, unix

Aug
07

Frontaux

C’est partie ! On commence le summer camp de façon technique avec la mise en place de la première brique de notre Infra Web Haute Dispo (http://madeinsyria.fr/2011/08/summer-camp-infra-web-haute-disponibilite/), les frontaux Web. Ils porteront principalement : Nginx et PHP5.

Pour rappel, j’ai choisis Nginx pour sa capacité à tenir, avec les même resources, une charge en moyenne dix fois superieur à celle d’un Apache2. De plus, il s’agit d’un serveur web qui gagne énormément en popularité, maitriser sa mise en place ne peut être qu’un plus !

Prérequis :

La configuration hardware des VM utilisées est la suivante :

  • 4vCPU
  • 1024Mo de RAM
  • 20Go de disque
  • 2 Cartes réseau sur les 2 Vlan (LB-FRONT et LB-BACK)

L’OS qui portera ce beau monde est : FreeBSD 8.2 x64. J’aime la robustesse et la stabilité de cet OS qui n’est en rien comparable à celle d’un Linux (oui, il y a un peu de troll dans l’histoire…).

 Installation de nginx

La version fournie par les package étant trop ancienne (0.8.53 vs 1.0.5 pour la version stable  actuelle), nous allons procéder à une installation via les sources.

Tout d’abord, installons les dépendances (la librairie pcre) :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports]# pkg_add -r pcre

Puis il faut récupérer la tarball nginx depuis le site. Pour cela on install “wget” puis on l’utilise pour récupérer la tarball :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# pkg_add -r wget
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# wget http://nginx.org/download/nginx-1.0.5.tar.gz

Il faut ensuite procéder à la décompression de la tarball et sa compilation. On ne peut plus classique :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# tar xzvf nginx-1.0.5.tar.gz
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# cd nginx-1.0.5/
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# ./configure \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --sbin-path=/usr/local/nginx/nginx \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --conf-path=/usr/local/etc/nginx/nginx.conf \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --pid-path=/var/run/nginx/nginx.pid \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --http-log-path=/var/log/nginx/access.log \
root@oaf-prj-web01.madeinsyria.fr-pts/0 <?># --with-http_ssl_module
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# make
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# make install

On se retrouve donc avec nginx installé dans /usr/local/nginx et le fichier de configuration dans /usr/local/etc/nginx/. Les logs seront placé dans /var/log/nginx.

On crée le script d’init pour finir, puis on le rend executable (le script est pompé du wiki Nginx) :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# vim /usr/local/etc/rc.d/nginx
##### Copié / Collé / Save / Exit #####
#!/bin/sh
 
NGINX_BASE_DIR="/usr/local/nginx/"
NGINX_DAEMON="${NGINX_BASE_DIR}/sbin/nginx"
NGINX_CONF="/usr/local/etc/nginx/nginx.conf"
 
__launch_signal( ) {
 
  ${NGINX_DAEMON} -s ${1} &amp;&gt;/dev/null
}
 
__checkconfig( ) {
 
  ${NGINX_DAEMON} -c ${NGINX_CONF} -t &amp;&gt;/dev/null
}
 
__start( ) {
 
  [ -r ${NGINX_CONF} ] || exit 1 
 
  __checkconfig &amp;&amp; ${NGINX_DAEMON} -c ${NGINX_CONF} &amp;&gt;/dev/null || return ${?}
}
 
__stop( ) {
 
  __launch_signal stop
}
 
__reload( ) {
 
  __checkconfig &amp;&amp; __launch_signar reload || return ${?}
}
 
__restart( ) {
 
  __stop &amp;&amp; __start
}
 
__show_usage( ) {
 
  echo "Usage: ${0} {start|stop|restart|reload}"
  exit 3
}
 
##
# :: main ::
case "${1}" in
  start|stop|restart|reload)
    [ -x ${NGINX_DAEMON} ] || exit 2
    __${1}
    ;;
  *)
    __show_usage
    ;;
esac
 
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# chmod +x /usr/local/etc/rc.d/nginx

 

Installation de PHP5

On install maintenant PHP5 avec le support CGI, pour cela :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# cd /usr/ports/lang/php52
root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports/lang/php52]# make config <span style="color: #ff0000;">#### Cocher FastCGI ####</span>
root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports/lang/php52]# make install &amp;&amp; make clean

Puis on install les extensions PHP généralement utilisés :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# cd /usr/ports/lang/php52-extensions
root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports/lang/php52-extensions]# make config <span style="color: #ff0000;">#### Cocher mcrypt, GD, toutes les PDO, MySQL, zlib ####</span>
root@oaf-prj-web01.madeinsyria.fr-pts/0 [/usr/ports/lang/php52-extensions]# make install &amp;&amp; make clean

Intégration Nginx/PHP5

Contrairement à Apache ou Lighttpd, Nginx ne sait pas faire appel de lui même (spawn) à FastCGI pour le traitement des requêtes PHP. Pour cela, il y a plusieurs façon de faire. Celle que je vais utiliser est baser sur la brique de Lighttpd : spawn-fcgi. (Option 2 : utiliser php-fpm).  Pour faire simple : l’utilisateur appel une page via Nginx (1). Nginx crée un proccess FastCGI via spawn-fcgi (php-fpm) (2), puis lui soumet la requête (3). La page executée (4) est alors renvoyé à l’utilisateur via Nginx (5).

 

Option 1 (spawn-cgi) :

On commence donc par télécharger et installer spawn-fcgi (la dernière version est dispo ici : http://redmine.lighttpd.net/projects/spawn-fcgi/news) :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# wget "http://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.bz2"
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# tar xzvf spawn-fcgi-1.6.3.tar.bz2
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# cd spawn-fcgi-1.6.3/
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~/spawn-fcgi-1.6.3]# ./configure
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~/spawn-fcgi-1.6.3]# make
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~/spawn-fcgi-1.6.3]# make install

On a donc un spawn-fcgi installé dans /usr/local/bin/.

Puis on crée notre script d’init et on le rend executable (bon il est pompé du wiki Nginx http://wiki.nginx.org ) :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# vim /usr/local/etc/rc.d/php-cgi
##### On colle le script suivant, on save and quit #####
#!/bin/sh
# Modified spawn-fcgi for rc.d (original: vivek@nixcraft.com)
NAME=php-cgi
SPAWNFCGI=/usr/local/bin/spawn-fcgi
FCGI_CHILDREN=3
PROCESS_NAME=lua
SERVER_SOCKET=/tmp/fcgi.socket
SERVER_PID=/tmp/fcgi.pid
SERVER_USER=www
SERVER_GROUP=www
FCGI_PROCESS=/usr/local/bin/php-cgi
SOCKSTAT=/usr/bin/sockstat
GREP=/usr/bin/grep
KILLALL=/usr/bin/killall
cmd=$1
fcgi_restart()
{
        fcgi_stop
        fcgi_start
}
fcgi_start()
{
        $SPAWNFCGI -s $SERVER_SOCKET -P $SERVER_PID -u $SERVER_USER -g $SERVER_GROUP -F $FCGI_CHILDREN -f $FCGI_PROCESS
}
fcgi_stop()
{
        $KILLALL $PROCESS_NAME
}
fcgi_status()
{
        $SOCKSTAT -u | $GREP -i $SERVER_SOCKET &gt; /dev/null
        [ $? -eq 0  ] &amp;&amp; echo "$PROCESS_NAME is running" || echo "$PROCESS_NAME is not running!"
}
fcgi_help()
{
        echo "Usage: $0 {(re)start|status|stop}"
}
case ${cmd} in
[Rr][Ee][Ss][Tt][Aa][Rr][Tt]) fcgi_restart;;
[Ss][Tt][Aa][Rr][Tt]) fcgi_start;;
[Ss][Tt][Oo][Pp]) fcgi_stop;;
[Ss][Tt][Aa][Tt][Uu][Ss]) fcgi_status;;
*) fcgi_help;;
esac
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# chmod +x /usr/local/etc/rc.d/php-cgi

Option 2 ( php-fpm ) :

C’est un paquet déjà installé avec php (si vous avez bien suivi les instructions…). Bah oui, facil. Il ne reste plus qu’à ajouter php-fpm en démarrage automatique via :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# echo 'php_fpm_enable="YES"' &gt;&gt; /etc/rc.conf

On peut alors démarrer FastCGI de la façon la plus classique avec le script d’init.

Pour finir, il ne reste plus qu’à ajuster la configuration de Nginx et tester !

Finalisation et test

Il suffit tout simplement de dire à Nginx de renvoyer les requêtes vers le FastCGI. La connexion se fait via la socket /tmp/fcgi.socket.

Pour faire simple, voici mon fichier de configuration, plus ou moins commenté (pour plus d’info, il y a la doc…) :

#User qui lance le process et nombre de fork
user www;
worker_processes  1;
 
#Error log et PID file
error_log  /var/log/error.log;
pid        /var/run/nginx/nginx.pid;
 
#Nombre max de clients par fork
events {
    worker_connections  1024;
}
 
#Gestion des connexions HTTP
http {
    include       mime.types;
    default_type  application/octet-stream;
 
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
 
    access_log  /var/log/access.log  main;
 
    sendfile        on;
    keepalive_timeout  15;
    gzip  on;
#Gestion des VHOST
    server {
        listen       80;
        server_name  test.madeinsyria.fr;
 
        access_log  /var/log/test.madeinsyria.fr.access.log  main;
 
        location / {
            root   html;
            index  index.html index.htm;
        }
 
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
#GESTION DU PHP
        location ~ \.php$ {
            #Dossier racine
            root           html;
            #On revoie vers la socket
            fastcgi_pass   unix:/tmp/fcgi.socket;
            fastcgi_index  index.php;
            #On défini le chemin des scripts php
            fastcgi_param  SCRIPT_FILENAME /usr/local/nginx/html/$fastcgi_script_name;
            include        fastcgi_params;
        }
    }
 
    # HTTPS server
    #
    #server {
    #    listen       443;
    #    server_name  localhost;
 
    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;
 
    #    ssl_session_timeout  5m;
 
    #    ssl_protocols  SSLv2 SSLv3 TLSv1;
    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers   on;
 
    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
 
}

Il suffit alors de faire une page php index.php, de mettre un phpinfo(); dedans et d’y accéder afin de valider le bon fonctionnement.

Pour finir, on passe les services Nginx et FastCGI en démarrage automatique. Pour cela :

root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# echo 'nginx_enable="YES"' &gt;&gt; /etc/rc.conf
root@oaf-prj-web01.madeinsyria.fr-pts/0 [~]# echo 'php_cgi_enable="YES"' &gt;&gt; /etc/rc.conf

Et voilà ! On a notre premier frontal web ! Il ne reste plus qu’à le cloner (bah oui, c’est une VM) pour faire le deuxième. La prochaine étape, c’est le serveur de fichiers statique en NFS, ça sera bien plus simple. On s’accroche !

A lire aussi :

  1. [Summer Camp] Infra Web Haute Disponibilité

Rédigé par

IT pro et passionné d'UNIX âgé de 22 ans, je cherche à partager quelques points de vu et mon savoir faire. N'hésitez pas à laisser un commentaire ou votre avis, ça enrichira le débat !

7 réponses to “[Summer Camp] Étape 1 – Frontaux Web (Nginx + PHP5)”

Afficher / Masquer les commentaires
  1. Lufyx says:

    Salut
    Donc déjà bravo pour ton initiative ,tes articles sont vraiment intéressant
    et je suis particulièrement intéressé par ton summer camp .

    Je suis actuellement entrain de mettre l’infra en place donc j’attends avec impatiente tes prochains billets ou si tu a des sources que je peut suivre pour avancer plus vite sa serai cool .

    Cdlt

    • MadeInSyria says:

      Merci bien ! Mon prochain billet arrive sous peu. Malheureusement, je n’ai pas de sources a proposer, moi même je n’entrouve pas. C’est d’ailleur pour ça que je rédige ces billets.

  2. Lufyx says:

    Bon pour la parti Haproxy c’est pas trop dur
    http://www.opensides.fr/2010/10/03/loadbalancing-et-failover-avec-haproxy/
    par contre mon probleme et plus au niveau serveur Nfs et Mysql

  3. Benjamin says:

    Bonjour,

    Très bon article ! Mais Pourquoi spawn-fcgi au lieux de php-fpm integré à php depuis la 5.3.3 ?

    • MadeInSyria says:

      Bonjour !

      Si j’ai mis en place spawn, c’est un peu par habitude. Il est clair qu’installer PHP-FPM serai plus “aux normes” et plus à jour. Pour le coup tu as gagné, j’ajoute les quelques lignes pour PHP-FPM

Laisser un commentaire