PHP-FPM

Allikas: Kuutõrvaja

PHP-FPM on lihtne ja robustne FastCGI protsessihaldur mis loodud php jaoks. Selle abil on võimalik üsna lihtsalt seadistada erinevatele apache või nginxi virtualhostidele erinevaid php versioone.

Tööpõhimõte

Tavaliselt kasutatakse apache veebiserveris php kasutamiseks spetsiaalset apache jaoks kirjutatud moodulit. Moodulite ja apache ehitusest tulenevalt ei saa lisada ühele apachele kahte php moodulit.

Veebipäring sellises traditsioonilises php keskkonnast näeb välja umbes sarnane:

Browser: Hei Apache, anna mulle sellel URLil olev html leht
Apache: (iseendale) OK, see on PHP url, las ma käivitan PHP mooduli, et saada HTML kätte.
Apache: OK browser,  siin on sinu HTML leht

Koos FastCGIga toimub see kujutletav protsess järgnevalt

Browser: Hei Apache, anna mulle sellel URLil olev html leht
Apache: (iseendale) OK, see leht viitab mu reeglites FastCGI URLile.
Apache FastCGI serverile: Kuule FastCGI server, käivita see programm selliste ja selliste parameetritega minu jaoks
FastCGI Server: OK, ma saadan selle php ja parameetrid edasi serverile, mis ma olen juba eelnevalt käivitanud ja mis väljastab HTMLi
FastCGI server: OK Apache server,  siin on sinu HTML leht
Apache: OK browser,  siin on sinu HTML leht

Paigaldamine Debianis

Paigaldame php5.6 ja 7.2 versioonid ja fpm pakid

sudo apt install php5.6 php5.6-fpm
sudo apt install php7.2 php7.2-fpm

Lisame php'dele mõned olulisemad moodulid

sudo apt-get install php5.6-cli php5.6-mysql php5.6-gd php5.6-recode php5.6-tidy php5.6-xmlrpc php5.6-opcache php5.6-mbstring
sudo apt-get install php7.2-cli php7.2-mysql php7.2-gd php7.2-recode php7.2-tidy php7.2-xmlrpc php7.2-opcache php7.2-mbstring

Paigaldamise järel käivituvad fastcgi deemonid automaatselt, saame seda kontrollida järgneva käsuga

# sudo systemctl status php5.6-fpm
  php5.6-fpm.service - The PHP 5.6 FastCGI Process Manager
   Loaded: loaded (/lib/systemd/system/php5.6-fpm.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2018-10-17 23:16:42 CEST; 1min 54s ago
     Docs: man:php-fpm5.6(8)
 Main PID: 30782 (php-fpm5.6)
   Status: "Processes active: 0, idle: 2, Requests: 0, slow: 0, Traffic: 0req/sec"
   CGroup: /system.slice/php5.6-fpm.service
           ??30782 php-fpm: master process (/etc/php/5.6/fpm/php-fpm.conf)
           ??30783 php-fpm: pool www
           ??30784 php-fpm: pool www

Seejärel lisame ka apachele fastcgi toe

# apt install apache2 libapache2-mod-fcgid
# a2enmod proxy_fcgi setenvif

Nüüd võime tekitada kaks veebilehte, millest üks kasutab üht ja teine teist php versiooni

Virtuaalhost 1 /etc/apache2/sites-available/php56.example.com.conf

<VirtualHost *:80>
    ServerName php56.example.com
    DocumentRoot /var/www/php56
    <Directory /var/www/php56>
        Options -Indexes +FollowSymLinks +MultiViews
        AllowOverride All
        Require all granted
    </Directory>
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php/php5.6-fpm.sock|fcgi://localhost/"
    </FilesMatch>
</VirtualHost>

Ja virtuaalhost 2 /etc/apache2/sites-available/php72.example.com.conf

<VirtualHost *:80>
    ServerName php72.example.com
    DocumentRoot /var/www/php72 
    <Directory /var/www/php72>
        Options -Indexes +FollowSymLinks +MultiViews
        AllowOverride All
        Require all granted
    </Directory>
    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php/php7.2-fpm.sock|fcgi://localhost/"
    </FilesMatch>
</VirtualHost>

Tekitame kaustad ning phpinfot väljastavad testfailid

sudo mkdir /var/www/php56
sudo mkdir /var/www/php72
echo "<?php phpinfo(); ?>" > /var/www/php56/index.php
echo "<?php phpinfo(); ?>" > /var/www/php72/index.php
sudo a2ensite php56.example.com
sudo a2ensite php72.example.com
sudo systemctl restart apache2

Pange tähele, et tõelise töö tegijaks on siin siis rida

SetHandler "proxy:unix:/var/run/php/php5.6-fpm.sock|fcgi://localhost/"

Mis antud juhul proxyib kõik php laiendiga failid fastcgi serveri soketile

Poolid

Vaikimisi käivitab fpm server nii php5.6 kui 7.2 koodi ühe pooli all mille nimeks www ja mis asub debian süsteemis /etc/php/5.6/fpm/pool.d/www.conf ja /etc/php/7.2/fpm/pool.d/www.conf

Pool failis on ära defineeritud lühidalt kasutaja, mille õiguses php fail käivitatakse, socketi nimi ja veel hulga parameetreid

[www]
user = www-data
group = www-data

listen = /run/php/php5.6-fpm.sock

listen.owner = www-data
listen.group = www.data
listen.mode = 0770

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.process_idle_timeout = 10s;
pm.max_requests = 500

; Pass environment variables
env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /srv/www/tmp
env[TMPDIR] = /srv/www/tmp
env[TEMP] = /srv/www/tmp
 
; host-specific php ini settings here
; php_admin_value[open_basedir] = /srv/www/:/tmp
php_admin_value[error_log] = /srv/www/log/fpm-php.log
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_value[realpath_cache_size] = 4096K

Juhul kui me soovime käivitada nii php5.6 kui 7.2 erinevate kasutajate õigustes tuleb meil luua neile mõlemale eraldi pool ja selles defineerida kasutajad ning socket failid.

/etc/php/5.6/fpm/pool.d/kasutaja.conf

; pooli nimi
[php56]
...
; kasutaja ja grupp mille õiguses php käivitatakse
user = kasutaja1
group =kasutaja1
...
; Socket millele apache ühendub
listen = /run/php/php5.6-fpm-kasutaja1.sock

Ja php7.2 jaoks /etc/php/7.2/fpm/pool.d/kasutaja.conf

; pooli nimi
[php72]
...
; kasutaja ja grupp mille õiguses php käivitatakse
user = kasutaja2
group =kasutaja2
...
; Socket millele apache ühendub
listen = /run/php/php7.2-fpm-kasutaja2.sock

Et neid uusi poole kasutada tuleb virtalhostide muuta olemasolevad socketid tekitatud saanutega. Kontrollides võime nüüd näha, et www pooli kõrval töötab ka kasutaja1 nimeline pool.

# sudo systemctl status php5.6-fpm
  php5.6-fpm.service - The PHP 5.6 FastCGI Process Manager
...
   CGroup: /system.slice/php5.6-fpm.service
           ├─15846 php-fpm: master process (/etc/php/5.6/fpm/php-fpm.conf)
           ├─15847 php-fpm: pool kasutaja1
           ├─15848 php-fpm: pool kasutaja1
           ├─15849 php-fpm: pool www
           └─15850 php-fpm: pool www

Kuid sellest siiski veel ei piisa, et võiks kasutaja kausta täielikult tema omaks kuulutada ja ülejäänud kasutajatele lugemine keelata. Miks? vaatame uuesti alguses olevat tabelit, kuidas Apache koos FastCGIga töötab. Selat võime näha, et failide lugemine toimub endiselt ikkagi apache poolt ja õigustes, vaid php failid käivitatakse nüüd kasutaja õigustes. Seega vajame me ikkagi ka mpm-itk workeri teenust

# apt-get install libapache2-mpm-itk

Apache konfidesse tuleb lisada täiendavalt järgnevad read

AssignUserId kasutaja1 kasutaja1

Ning sama kasutaja2 kohta teise konfi

Lingid

https://alanstorm.com/php-fpm-and-file-permissions/