Table des matières

Nginx & PHP

Sur une base Alpine Linux, en suivant https://wiki.alpinelinux.org/wiki/Nginx_with_PHP

Installation et configuration de base

On commence par installer Nginx :

apk add nginx tzdata openssl memcached

On crée l'utilisateur www qui va gérer le service nginx :

adduser -D -g 'www' www

On crée les dossiers dont on a besoin, et on donne les droits à l'utilisateur www :

mkdir /www
chown -R www:www /var/lib/nginx
chown -R www:www /www

On vire la configuration nginx par défaut, et on crée la notre :

mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.orig
nano /etc/nginx/nginx.conf
user                            www;
worker_processes                auto; # it will be determinate automatically by the number of core

error_log                       /var/log/nginx/error.log warn;
#pid                             /var/run/nginx.pid; # it permit you to use /etc/init.d/nginx reload|restart|stop|start

events {
    worker_connections          1024;
}

http {
    server_tokens off;
    include                     /etc/nginx/mime.types;
    default_type                application/octet-stream;
    sendfile                    on;
    access_log                  /var/log/nginx/access.log;
    keepalive_timeout           3000;
    
    server {
        listen                  80;
        root                    /www;
        index                   index.html index.htm;
        server_name             localhost;
        client_max_body_size    32m;
        error_page              500 502 503 504  /50x.html;
        
        location = /50x.html {
              root              /var/lib/nginx/html;
        }
    }
}

Au besoin, on teste la configuration et la syntaxe :

nginx -t

Service

Installer nginx en tant que service :

rc-service nginx reload
rc-update add nginx default

Un petit reboot, et tester que le service est bien en route :

reboot
[...]
#Tester l'existence du service
ps aux | grep nginx

Si tout va bien, on retrouve notre processus :

386 root       0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  387 www        0:00 nginx: worker process
  388 www        0:00 nginx: worker process
  389 www        0:00 nginx: worker process
  390 www        0:00 nginx: worker process
  401 root       0:00 grep nginx

PHP

Installation de PHP en version 7, et ses principaux modules :

apk add php7-fpm php7-mcrypt php7-soap php7-openssl php7-gmp php7-pdo_odbc php7-json php7-dom php7-pdo php7-zip php7-mysqli php7-sqlite3 php7-apcu php7-pdo_pgsql php7-bcmath php7-gd php7-odbc php7-pdo_mysql php7-pdo_sqlite php7-gettext php7-xmlreader php7-xmlrpc php7-bz2 php7-memcached php7-iconv php7-pdo_dblib php7-curl php7-ctype php7-common php7-xml php7-pgsql php7-imap php7-posix php7-ldap
#Pour Shaarli
apk add php7-zlib
#Pour FreshRSS
apk add php7-fileinfo php7-intl php7-mbstring php7-simplexml
#Pour Nextcloud
apk add php7-xmlwriter php7-ctype php7-dom php7-gd php7-iconv php7-json php7-xml php7-mbstring php7-posix php7-simplexml php7-xmlwriter php7-zip php7-zlib php7-pdo_mysql php7-curl php7-fileinfo php7-bz2 php7-intl php7-mcrypt php7-openssl

Pour les fichiers de configuration, on utilise la méthode du wiki Alpine en commençant par définir nos variables, en adaptant à nos besoins :

PHP_FPM_USER="www"
PHP_FPM_GROUP="www"
PHP_FPM_LISTEN_MODE="0660"
PHP_MEMORY_LIMIT="512M"
PHP_MAX_UPLOAD="16G"
PHP_MAX_FILE_UPLOAD="200"
PHP_MAX_POST="16G"
PHP_DISPLAY_ERRORS="Off"
PHP_DISPLAY_STARTUP_ERRORS="On"
PHP_ERROR_REPORTING="E_COMPILE_ERROR\|E_RECOVERABLE_ERROR\|E_ERROR\|E_CORE_ERROR"
PHP_CGI_FIX_PATHINFO=0

Et on lance les procédures de modification sur php-fpm.conf (attention à l'emplacement du fichier .conf) :

sed -i "s|;listen.owner\s*=\s*nobody|listen.owner = ${PHP_FPM_USER}|g" /etc/php7/php-fpm.d/www.conf
sed -i "s|;listen.group\s*=\s*nobody|listen.group = ${PHP_FPM_GROUP}|g" /etc/php7/php-fpm.d/www.conf
sed -i "s|;listen.mode\s*=\s*0660|listen.mode = ${PHP_FPM_LISTEN_MODE}|g" /etc/php7/php-fpm.d/www.conf
sed -i "s|user\s*=\s*nobody|user = ${PHP_FPM_USER}|g" /etc/php7/php-fpm.d/www.conf
sed -i "s|group\s*=\s*nobody|group = ${PHP_FPM_GROUP}|g" /etc/php7/php-fpm.d/www.conf
sed -i "s|;log_level\s*=\s*notice|log_level = notice|g" /etc/php7/php-fpm.d/www.conf #uncommenting line 

On pourra aussi regarder du côté de https://myshell.co.uk/blog/2012/07/adjusting-child-processes-for-php-fpm-nginx/ pour ajuster le nombre de process PHP-FPM, du style :

pm.max_children = 16
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200

Et si l'on veut une page de statut du pool PHP-FPM :

pm.status_path = /status
ping.path = /ping

Tout en s'assurant que le chemin soit disponible pour PHP, par exemple dans les blocs server :

location ~ ^/(status|ping)$ {
     access_log off;
     # On autorise le serveur lui-même
     allow 127.0.0.1;
     # On peut rajouter une seconde IP autorisée, si besoin ou plus
     allow 10.1.1.0/24;
     deny all;
     include fastcgi_params;
     fastcgi_pass 127.0.0.1:9000;
}

Finalement, les pages suivantes seront disponibles avec les informations sur le pool :

http://domain.tld/status
    http://domain.tld/status?json
    http://domain.tld/status?html
    http://domain.tld/status?xml

    http://domain.tld/status?full
    http://domain.tld/status?json&full
    http://domain.tld/status?html&full
    http://domain.tld/status?xml&full

Et ensuite les modifications sur php.ini :

sed -i "s|display_errors\s*=\s*Off|display_errors = ${PHP_DISPLAY_ERRORS}|i" /etc/php7/php.ini
sed -i "s|display_startup_errors\s*=\s*Off|display_startup_errors = ${PHP_DISPLAY_STARTUP_ERRORS}|i" /etc/php7/php.ini
sed -i "s|error_reporting\s*=\s*E_ALL & ~E_DEPRECATED & ~E_STRICT|error_reporting = ${PHP_ERROR_REPORTING}|i" /etc/php7/php.ini
sed -i "s|;*memory_limit =.*|memory_limit = ${PHP_MEMORY_LIMIT}|i" /etc/php7/php.ini
sed -i "s|;*upload_max_filesize =.*|upload_max_filesize = ${PHP_MAX_UPLOAD}|i" /etc/php7/php.ini
sed -i "s|;*max_file_uploads =.*|max_file_uploads = ${PHP_MAX_FILE_UPLOAD}|i" /etc/php7/php.ini
sed -i "s|;*post_max_size =.*|post_max_size = ${PHP_MAX_POST}|i" /etc/php7/php.ini
sed -i "s|;*cgi.fix_pathinfo=.*|cgi.fix_pathinfo= ${PHP_CGI_FIX_PATHINFO}|i" /etc/php7/php.ini

On peut aussi jouer sur le cache PHP :

# Taille du cache alloué en MB
opcache.memory_consumption=128
# Nombre de scripts PHP à garder en cache max (200 < X < 100000)
opcache.max_accelerated_files=10000
# % de mémoire gaspillée max avant reboot cache
opcache.max_wasted_percentage=10
# Vérifier les mises à jour de script
opcache.validate_timestamps=1
# Fréquence à laquelle vérifier les mises à jour : 0 pour toujours vérifier
opcache.revalidate_freq=0

On retourne éditer notre fichier de configuration original de nginx pour ajouter le support de PHP :

nano /etc/nginx/nginx.conf
user                            www;
worker_processes                1;

error_log                       /var/log/nginx/error.log warn;
#pid                             /var/run/nginx.pid;

events {
    worker_connections          1024;
}

http {
    server_tokens off;
    include                     /etc/nginx/mime.types;
    default_type                application/octet-stream;
    sendfile                    on;
    access_log                  /var/log/nginx/access.log;
    keepalive_timeout           3000;
    
    server {
        listen                  80;
        root                    /www;
        index                   index.html index.htm index.php;
        server_name             localhost;
        client_max_body_size    32m;
        error_page              500 502 503 504  /50x.html;
        
        location = /50x.html {
            root              /var/lib/nginx/html;
        }
        
        location ~ \.php$ {
            #fastcgi_pass     unix:/var/run/php7-fpm.sock;
            fastcgi_pass      127.0.0.1:9000;
            fastcgi_index     index.php;
            include           fastcgi.conf;
        }
    }
}

On met en place la configuration du serveur de temps :

TIMEZONE="Europe/Paris"
cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime
echo "${TIMEZONE}" > /etc/timezone
sed -i "s|;*date.timezone =.*|date.timezone = ${TIMEZONE}|i" /etc/php7/php.ini

On crée un fichier de test et on l'édite :

nano /www/phpinfo.php
<?php
	phpinfo();
?>

On redémarre nos services, et on regarde si la page s'affiche bien :

rc-service nginx restart
rc-service php-fpm7 start

Si tout OK, on active le service PHP-FPM et on reboot tester :

rc-update add php-fpm7 default
reboot

Enfin, pensez à bien changer la variable server_name dans votre fichier de configuration nginx, /etc/nginx/nginx.conf.