# Nginx et PHP-FPM en chroot

NGINX, PHP-FPM chrootés, sur CentOS

Lien : [http://publications.jbfavre.org/web/php-fpm-apps-server-nginx.fr](http://publications.jbfavre.org/web/php-fpm-apps-server-nginx.fr) (documentation sur Debian)

# <span class="mw-headline" id="bkmrk-installation-0">Installation</span>

Ajouter les dépôts Remi, RPMForge et EPEL (-&gt; [Dépôts complémentaires](https://wiki.kogite.fr/index.php/D%C3%A9p%C3%B4ts_compl%C3%A9mentaires "Dépôts complémentaires")).

```
yum install --enablerepo=epel nginx
yum install --enablerepo=remi php-fpm
yum install --enablerepo=rpmforge mod_fastcgi
```

La configuration de PHP-FPM se trouve dans /etc/php-fpm.conf et /etc/php-fpm.d/\* et celle de NGINX dans /etc/nginx, /etc/nginx/conf.d/ et /usr/share/nginx.

Pour valider le fonctionnement après installation, on va seulement activer le site par défaut avec PHP-FPM.

Dans /etc/nginx/nginx.conf, décommenter

```
       location ~ \.php$ {
           root           html;
           fastcgi_pass   127.0.0.1:9000;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
           include        fastcgi_params;
       }
```

Modifier éventuellement le port, au cas ou Apache est lancé aussi, et utilise déjà le port 80. Pour l'exemple nous utiliserons :

```
    server {
       listen       8080;
       ....
```

et vérifier que nginx ne se lancera pas en tant que root :

```
user              nginx;
```

Lancer nginx et php-fpm.

```
service nginx start
service php-fpm start
```

Tester :

```
echo "<?php phpinfo();" > /usr/share/nginx/html/phpinfo.php
```

et afficher phpinfo.php dans un navigateur.

Si APC est installé, copier la page de stats

```
cp /usr/share/doc/php-pecl-apc-*/apc.php /usr/share/nginx/html/
```

et afficher apc.php dans un navigateur.

# <span class="mw-headline" id="bkmrk-chroot-0">Chroot</span>

Si nginx et php-fpm fonctionnent, on peut maintenant chrooter php-fpm. Dans /etc/nginx.conf, commenter tout le bloc "server {...." du site par défaut, on en aura plus besoin puisqu'à priori on va plutôt utiliser des virtualhosts séparés.

Créer un répertoire, par exemple /home/chroot :

```
mkdir /home/chroot
chown nginx.nginx /home/chroot
```

<u>1.NGINX</u>  
Dans /etc/nginx/nginx.conf, re-commenter le bloc "location ~ \\.php$ { ..... }", le vhost par défaut n'en aura pas besoin.

On crée un virtualhost dans /etc/nginx/conf.d/virtual.conf :

```
server {
   listen       8080;
   server_name  monvhost.domaine.fr;
   root   /home/chroot/monvhost/;
       location / {
           index  index.php;
       }
       location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico)$ {
           access_log        off;
           expires           max;
           add_header Pragma public;
           add_header Cache-Control "public, must-revalidate, proxy-revalidate";
       }
       error_page  404              /404.html;
       location = /404.html {
           root   /usr/share/nginx/html;
       }
       error_page   500 502 503 504  /50x.html;
       location = /50x.html {
           root   /usr/share/nginx/html;
       }
       fastcgi_intercept_errors on;
       location ~ \.php$ {
           fastcgi_pass   127.0.0.1:9000;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME  $fastcgi_script_name;
           include        fastcgi_params;
       }
}
```

*Note 1 : au passage, on a ajouté un peu de cache sur les objet statiques, images, css, etc...*  
*Note 2 : le "root" doit être déclaré au niveau "server" pour être propagé ensuite dans les blocs "location", notamment pour que le cache ajouté ci-dessus fonctionne.*

<u>2. FPM</u>  
Un fichier d'exemple /etc/php-fpm.d/www.conf a du être créé au moment de l'installation. Garder ce fichier pour références futures (il est bien documenté) en le renommant www.conf.sample (il ne sera donc pas interprété au lancement de php-fpm, ça évitera de consommer des ressources inutilement).

Dupliquer ce fichier pour créer un "pool" correspondant au virtualhost de nginx :

```
mv /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.sample
cp /etc/php-fpm.d/www.conf.sample /etc/php-fpm.d/monvhost.conf
```

Dans /etc/php-fpm.d/monvhost.conf, renommer éventuellement le nom de pool entre crochets (on peut laisser \[www\], mais c'est moins propre !). On vérifie que :

```
listen = 127.0.0.1:9000
```

est décommenté (nginx cherchera ce port d'après sa configuration fastcgi\_pass).

On décommente et on modifie :

```
listen.owner = nginx
listen.group = nginx
```

et

```
user = nginx
group = nginx
```

on décommente et on modifie :

```
chroot = /home/chroot/monvhost
```

Une fois le ménage fait, on doit donc avoir un fichier de ce type :  
(**Note** : les options php\_flag et php\_admin à la fin dépendent des besoins de l'application chrootée)

```
[monvhost]
listen = 127.0.0.1:9000
listen.owner = nginx
listen.group = nginx
listen.mode = 0666
listen.backlog = -1
;listen.allowed_clients = 127.0.0.1

user = nginx
group = nginx

pm = dynamic
pm.max_children = 50
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 35
;pm.max_requests = 500
pm.status_path = /status

request_terminate_timeout = 2
request_slowlog_timeout = 1
slowlog = /var/log/php-fpm/www-slow.log
;rlimit_files = 1024
;rlimit_core = 0

chroot = /home/chroot/monvhost
catch_workers_output = yes
 
env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 32M
php_admin_value[upload_max_filesize] = 8M
php_value[max_execution_time] = 2
php_value[include_path] = .:/usr/share/pear:/usr/share/php
```

PHP requiert quelques répertoires pour fonctionner, ainsi que les fichiers de timezone du système. Comme il est chrooté, il faut les copier :

```
mkdir -p /home/chroot/monvhost/{etc,usr/share,var/lib/php/session,tmp}
cp /etc/localtime /home/chroot/monvhost/etc
cp -r /usr/share/zoneinfo /home/chroot/monvhost/usr/share/
chown -R nginx.nginx /home/chroot/monvhost
```

Touche finale : copier les logos de Nginx localement afin que les pages d'erreur 40x et 50x n'affichent pas de liens cassés

```
cp /usr/share/nginx/html/*.png /home/chroot/monvhost
```

Déplacer les fichiers phpinfo.php et apc.php de /home/chroot vers monvhost. Tester.

# <span class="mw-headline" id="bkmrk-virtualhosts-0">Virtualhosts</span>

Pour créer d'autres virtualhosts, dupliquer /etc/php-fpm.d/monvhost.conf. Dans le nouveau fichier (qui créera donc un nouveau "pool" FPM), modifier le port (incrémenter par exemple à 9001, puis 9002,...) et la ligne chroot.

De même, dupliquer ensuite le bloc "server { ...... } " dans /etc/nginx/conf.d/virtual.conf, apporter les modifications nécessaires au nom du serveur (virtualhost), au chemin root, et au port de "fastcgi\_pass".

# <span class="mw-headline" id="bkmrk-ssl-0">SSL</span>

Pour autoriser le SSL (http**s**://...) dans nginx, créer des certificats :

```
cd /usr/share/nginx/
mkdir ssl
cd ssl
openssl req -new -x509 -nodes -out nginx.crt -keyout nginx.key
```

Ajouter dans /etc/nginx/conf.d/virtual.conf, dans le bloc "server {..." du virtualhost qui doit supporter le SSL :

```
   listen       8080 <strong>default_server ssl</strong>;
...
   ssl_certificate /usr/share/nginx/ssl/nginx.crt;
   ssl_certificate_key /usr/share/nginx/ssl/nginx.key;
   ssl_protocols        SSLv3 TLSv1 SSLv2;
   ssl_ciphers          HIGH:!aNULL:!MD5;
   ssl_session_timeout 5m;
```

*Noter la modification de la ligne "listen" pour activer le ssl. Cette syntaxe est obligatoire depuis Nginx v0.7, la précédente option "ssl on;" n'est plus reconnue*

Le port peut être celui qu'on veut, le 443 n'est pas une obligation, juste une valeur par défaut pour les navigateurs.

# <span class="mw-headline" id="bkmrk-tips-0">TIPS</span>

## <span class="mw-headline" id="bkmrk-modifications-param%C3%A8-0">Modifications paramètres PHP</span>

Pour modifier des paramètres PHP spécifiquement pour chaque virtualhost, éditer /etc/php-fpm.d/monvhost.conf, ajouter des lignes du type :

```
php_admin_value[upload_max_filesize] = 8M
```