• Ce blog — désormais archivé — est en lecture seule.

Dédibox v3 : Nginx + PHP-FPM + Apache2 + APC + Memcached + MySQL

Bonjour :-)

J’ai récemment pris une Dédibox v3 et pour le moment j’en suis très satisfait. On m’a pas mal sollicité ces derniers temps pour que j’explique comment j’ai configuré ce serveur ainsi que les services que j’ai pu mettre en place. C’est l’objet de cet article.

Premièrement, j’utilise Debian depuis toujours et c’est logiquement ce qui tourne sur la Dédibox (en version 64 bits).

Le serveur HTTP frontal n’est pas Apache2 mais Nginx (wiki) que j’ai appréhendé seulement depuis l’obtention de ce serveur. Et je dois avouer que j’en suis très satisfait, terriblement surpris d’ailleurs. Apache2 est bien en place mais sert de proxy à Nginx.

Nginx est couplé à php-fpm. La paire formée est excellente et permet l’utilisation de Memcached ou APC sans soucis. Notons que l’excellent repository Dotdeb fournit un package .deb de php-fpm. Ce repository est certainement un must-have puisque Debian n’est pas forcément très en avance sur les versions de PHP. Pour ma part, j’ai installé, via ce repository, PHP 5.3.2 ainsi que la dernière version d’APC (3.1.2 via pecl). Comme je l’ai dit plus haut j’ai installé Memcached avec l’extension PHP qui va bien. Passons à la configuration.

Nginx

user www-data;
worker_processes 1;

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;

client_max_body_size 8M;

sendfile            on;
keepalive_timeout   15;
tcp_nodelay         on;

# Enable Gzip compression
gzip on;
gzip_disable "MSIE [1-6].(?!.*SV1)";
gzip_vary on;
gzip_comp_level 3;
gzip_proxied any;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_buffers 16 8k;

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

Le paramètre worker_processes dépend de votre processeur (multi-coeurs ou non). Dans le cas d’une Dédibox, on ne dispose que d’un processeur mono-coeur donc on fixe ce paramètre à 1. Ensuite j’active la compression gzip, ce qui permettra de gagner un peu en performances (moins de données à envoyer d’un coup = plus de données envoyées en même temps).

Nginx va servir tous les fichiers statiques, les « assets » mais également les pages en cache. Il s’interface très bien avec Memcached. Il est aussi capable de servir n’importe quel fichier sur disque.

Voici les deux autres fichiers de configuration de Nginx : proxy.conf pour configurer Apache2 en proxy et fastcgi_params pour php-fpm.

# /etc/nginx/proxy.conf
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;
proxy_connect_timeout           90;
proxy_send_timeout              90;
proxy_read_timeout              90;
proxy_buffer_size               4k;
proxy_buffers                   4 32k;
proxy_busy_buffers_size         64k;
proxy_temp_file_write_size      64k;
# /etc/nginx/factcgi_params
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

# Custom settings
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

Pour utiliser Apache2 en proxy ou php-fpm, il suffit d’insérer quelques lignes dans vos configurations de vhosts. C’est suffisamment détaillé ailleurs, je n’y reviendrai donc pas.

APC

Voilà ma configuration APC, fonctionne bien pour Symfony. Pour certaines applis dont le code laisse à désirer, je suggère de passer le paramètre include_once_override à 0. Cette config provient en grande partie de chez Romain Cambien.

[apc]
apc.enabled=1

; 1 segments of 256Mo
apc.shm_segments=1
apc.shm_size=256

; No optimization
apc.optimization=0

; Never expire
apc.ttl=0
apc.user_ttl=0

; workaround for CLI
apc.enable_cli=1

; Symfony make lot of path lookups, try to optimize
apc.include_once_override=1
apc.canonicalize=1

; Wait 2 seconds to rebuild cache
apc.file_update_protection=2

PHP

La configuration de PHP est celle par défaut aux best practices près (short_tags off, magic quote gpc off, …). J’ai surtout calqué sur les « requirements » de Diem. A noter que l’on gère 3 fichiers php.ini : pour Apache2, pour php-fpm et pour cli.

Memcached

Aucun besoin de modifier la configuration par défaut. Par contre, on peut modifier la taille (64Mo par défaut) si besoin.

Apache2

Pour utiliser Apache2 en proxy, on doit nécessairement lui attribuer un port différent du port par défaut (80). Pour cela, on modifie le fichier /etc/apache2/ports.conf :

# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default
# This is also true if you have upgraded from before 2.2.9-3 (i.e. from
# Debian etch). See /usr/share/doc/apache2.2-common/NEWS.Debian.gz and
# README.Debian.gz

Listen 9999
NameVirtualHost *:9999
# SSL name based virtual hosts are not yet supported, therefore no
# NameVirtualHost statement here
Listen 443

J’ai choisi le prefork MPM d’Apache2, la directive KeepAlive est désactivé car Apache2 ne sert que du PHP. Après quelques tests, voici la configuration retenue :

# Timeout: The number of seconds before receives and sends time out.
Timeout 10

# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
KeepAlive Off

# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
MaxKeepAliveRequests 100

# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
KeepAliveTimeout 2

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
StartServers          8
MinSpareServers       5
MaxSpareServers      15
MaxClients           80
MaxRequestsPerChild   0

MySQL

En SGBD, j’ai installé MySQL et PostgreSQL qui ne sert pas pour le moment. La configuration MySQL est d’origine à l’exception d’un Ramdisk pour le répertoire temporaire. L’explication pour la création d’un Ramdisk est expliqué ici : /optimiser-son-application-web-en-jouant-sur-php-mysql-et-apache2/. MySQL est également protégé par une couche Memcached, ce qui permet de faire tenir une charge correcte sans envoyer MySQL dans les choux.

Postfix

Configuré en « Site Internet », rien n’a été touché et les mails transitent bien. Je n’ai pas besoin de faire de gestion de mail autre.

Getmail

Dernière petite chose qui n’avait pas été relevé dans l’article précédent : /sauvegarde-incrementale-avec-rsync-fichiers-et-base-de-donnees-mysql/, la sauvegarde de mes emails. Tout est dit ici. J’envoie toutes mes sauvegardes sur un autre serveur privé et inaccessible excepté le temps du transfert.

Voilà.

  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Twitter
  • Google Bookmarks
  • FriendFeed
  • LinkedIn
  • MySpace
  • Netvibes
  • PDF
  • Ping.fm
  • RSS
  • Technorati
  • viadeo FR
  • Wikio
  • Yahoo! Buzz

Related Posts

Cet article a été publié dans Serveur, Sysadmin avec les mots-clefs : , , , , , , , , . Bookmarker le permalien. Les commentaires et les trackbacks sont fermés.

2 commentaires

  1. Aston
    Le 25 novembre 2010 à 21 h 06 min | Permalien

    Merci pour cette article.

    Juste une question, à quoi sert apache2 si php-fpm est utilisé par nginx pour le php. Et inversement, si apache2 est utilisé pour le php, quel est l’utilité de php-fpm ?

    « Nginx est couplé à php-fpm » – « Apache2 est bien en place mais sert de proxy à Nginx »

    Je ne vois pas vraiment l’utilité d’Apache2: dans quel cas est-il utilisé par Nginx si celui-ci est déjà couplé à php-fpm.
    Si quelqu’un pouvait m’éclairer ça ne serait pas de refus.

    • Le 25 novembre 2010 à 21 h 14 min | Permalien

      Bonsoir,

      La configuration décrite permet d’utiliser les deux serveurs web Apache2 et Nginx, voilà tout.
      Ceci me permet de faire des tests Apache2 vs Nginx, de pouvoir travailler avec Apache2 tout en ayant un proxy Nginx pour servir du contenu statique, mais également de pouvoir tester PHP-FPM grâce à Nginx.

      Pour info, beaucoup de sites tournent encore avec Apache2 + mod_php pour tout ce qui est PHP et ajoutent Nginx (sans PHP-FPM) en reverse proxy pour gérer cache et fichiers statiques.

      Cordialement,
      Will.