Nginx mit PHP-FPM [Update]

Howto, Nginx, PHP, PHP-FPM, Serverdienste, Ubuntu, Webserver Kommentare (1)

Nginx gilt seit geraumer Zeit als Shootingstar unter den Webservern (neueste Zahlen führen Nginx bereits vor Microsofts IIS). Diese Anleitung soll helfen Nginx als Apache Ersatz für die eigene Produktivumgebung zu etablieren. Besonderes Augenmerk wird dabei auf die Verwendung von Nginx mit PHP-FPM gelegt.

History

05.05.2011: +Ruby: Nginx + Ruby + …
10.02.2012: Änderung Konfigurationsparameter PHP
20.04.2012: Konfiguration & Verbindung zwischen PHP/Nginx hinzugefügt

 

Speed: Nginx

Vorarbeiten

Es sind einige Abhängigkeiten zu bedienen bevor Nginx PHP-FPM mit dem gewünschten Funktionsumfang kompiliert werden kann. Je nach gewünschtem Funktionsumfang variieren diese. Auf dem Laborsystem dieser Anleitung genügte das Nachinstallieren folgender Pakete mit apt.

apt-get install libperl-dev libssl-dev libxcrypt-dev
apt-get install bison autoconf build-essential

3-Satz

Übersetzt wird Nginx mit diversen Parametern, die man im Wiki nachlesen kann. Ob diese im Einzelnen notwendig sind entscheidet der Leser. Hier hilft auch ein Blick auf die Module-Seite. Zunächst ist der Quellcode herunterzuladen.

wget http://nginx.org/download/nginx-1.x.x.tar.gz
tar xvf nginx-1.x.x.tar.gz
cd nginx-1.x.x

Anschließend wird übersetzt und installiert. Zunächst werden die Quellen vorbereitet und gelinkt. Der Prefix-Pfad wird hier in der Anleitung auf /srv/nginx gesetzt. Es empfiehlt sich an dieser Stelle auf blindes Kopieren der Compiler-Anweisungen zu verzichten und die entsprechenden Direktiven zu verifizieren. Insbesondere --with-cpu-opt.

./configure --prefix=/srv/nginx \
   --conf-path=/srv/nginx/etc/nginx.conf \
   --http-log-path=/srv/nginx/log/access.log \
   --error-log-path=/srv/nginx/log/error.log \
   --pid-path=/srv/nginx/var/nginx.pid /
   --http-proxy-temp-path=/srv/nginx/tmp/proxy \
   --http-fastcgi-temp-path=/srv/nginx/tmp/fastcgi \
   --http-uwsgi-temp-path=/srv/nginx/tmp/uwsgi \
   --http-scgi-temp-path=/srv/nginx/tmp/scgi \
   --http-client-body-temp-path=/srv/nginx/tmp/client_body \
   --with-sha1-asm \
   --with-sha1=/usr/lib \
   --with-http_realip_module \
   --with-http_ssl_module \
   --with-http_perl_module \
   --with-cpu-opt=amd64 \
   --with-http_flv_module \
   --with-http_gzip_static_module \
   --with-http_secure_link_module \
   --with-http_stub_status_module \
   --with-http_addition_module \
   --with-http_sub_module

Soll auf bestimmte Funktionen verzichtet werden, bspw. die Fähigkeit als Proxy für bestimmte Protokolle zu dienen, so sind diese ggf. auszuschliessen.

--without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module

Neben diesen und weiteren Parametern können mittels –with-debug verschiedene Debug-Optionen aktiviert werden. Darunter auch Die Möglichkeit der Debug-Logausgabe.

Der Abschluss des Konfigurieren sollte, in Abhängigkeit der gewählten Schalter in etwa so aussehen:

Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + md5: using OpenSSL library
  + using sha1 library: /usr/lib
  + using system zlib library
 
  nginx path prefix: "/srv/nginx"
  nginx binary file: "/srv/nginx/sbin/nginx"
  nginx configuration prefix: "/srv/nginx/etc"
  nginx configuration file: "/srv/nginx/etc/nginx.conf"
  nginx pid file: "/srv/nginx/var/nginx.pid"
  nginx error log file: "/srv/nginx/log/error.log"
  nginx http access log file: "/srv/nginx/log/access.log"
  nginx http client request body temporary files: "/srv/nginx/tmp/client_body"
  nginx http proxy temporary files: "/srv/nginx/tmp/proxy"
  nginx http fastcgi temporary files: "/srv/nginx/tmp/fastcgi"
  nginx http uwsgi temporary files: "/srv/nginx/tmp/uwsgi"
  nginx http scgi temporary files: "/srv/nginx/tmp/scgi"

Was folgt ist das Übersetzten und Installieren:

make
make install

Nacharbeiten

Die Temp-Verzeichnisse werden mit ‚make install‘ nicht angelegt und sind daher Bestandteil der Nacharbeiten in dieser Anleitung.

mkdir /srv/nginx/tmp/{proxy,uwsgi,scgi,fastcgi,client_body}

Als weiteren Schritt bereiten wir Nginx auf einen reibungslosen Update-Vorgang vor. Dazu wird das Installationsverzeichnis zunächst verschoben, dann zurück verlinkt.

cd /srv
mv nginx nginx-versionsnummer
ln -s nginx-versionsnummer nginx

PHP-FPM

Bei php-fpm handelt es sich um einen PHP FastCGI Process Manager der sich besonders für stark frequentierte Seiten eignet. Weiterführende Informationen erhält man auf der Homepage des Projektes. Erwähnt sei allerdings ein maßgeblicher Vorteil von FastCGI, die Isolierung der Skriptsprache vom Webserver, sprich der Gewinn an Sicherheit für das Webserver-Konstrukt.

Abhängigkeiten

Auch hier sind wieder Abhängigkeiten aufzulösen. Ob diese im Details ausreichen, hängt vom Zustand des Systems ab.

apt-get install libcurl4-gnutls-dev libjpeg62-dev libpng12-dev libmcrypt-dev \
                libfreetype6-dev libt1-dev libc-client2007-dev libbz2-dev libxml2-dev \
                libmysqlclient15-dev

Auf einem frischen System werden von der Selektion abhängige Pakete nachinstalliert.

Noch ganz frisch?

Wer sein Glück unter Ubuntu 8.04 versucht, benötigt eine neuere Version von libevent. Die unter 8.04 verwendete läßt den Compiler abbrechen. Abhilfe schafft hier die Installation der aktuellen Libs. Damit entzieht sich libevent allerdings dem Updateprozess von apt-get!

wget libevent-1.4.14b-stable.tar.gz
tar xvf libevent-1.4.14b-stable.tar.gz
cd libevent-1.4.14b-stable
./configure --prefix=/usr/local/lib/libevent
make
make install

Für das Linken und Kompilieren ist es noch notwendig, dass das System vom Installationsverzeichnis der Library Kenntnis hat. Das geschieht z.B. durch eintragen von include /usr/local/lib in /etc/ld.so.conf und dem Aufruf von ldconfig.

Yet Another 3-Satz

Es gilt das gleiche wie für das Kompilieren von Nginx. Downloaden, Konfigurieren und Übersetzen. Allerdings immer mit den aktuellsten Paketen! Daher entsprechend unter php.net nachsehen und den wget Downloadlink anpassen! (10.02.2012)

wget http://de3.php.net/get/php-5.x.x.tar.bz2/from/this/mirror
tar xvf php-5.x.x.tar.bz2
cd php-5.x.x
./configure --prefix=/srv/php \
   --with-pear=/srv/php/pear \
   --with-sysconfdir=/etc/php5 \
   --enable-mod-charset \
   --enable-fpm \
   --with-libxml-dir=shared,/usr/lib \
   --with-openssl=shared \
   --with-kerberos=shared \
   --with-zlib=shared \
   --enable-bcmath \
   --with-bz2=shared \
   --enable-calendar \
   --with-curl=shared \
   --with-curlwrappers \
   --enable-dba=shared \
   --enable-ftp \
   --with-gd \
   --with-jpeg-dir=/usr/lib \
   --enable-gd-native-ttf \
   --with-sqlite=shared \
   --with-pdo-mysql \
   --with-mysqli=/usr/bin/mysql_config \
   --with-freetype-dir=/usr/lib \
   --with-xpm-dir=/usr/lib \
   --with-t1lib \
   --with-mcrypt \
   --enable-mbstring \
   --with-mysql \
   --with-mysql-sock \
   --with-mysqli=/usr/bin/mysql_config \
   --enable-soap \
   --enable-sysvmsg \
   --enable-sysvsem \
   --enable-sysvshm \
   --enable-zip \
   --enable-shared \
   --with-mysql=mysqlnd \
   --with-mysqli=mysqlnd \
   --with-pdo-mysql=mysqlnd \
   --with-xsl
make
make install

Ziellinie

Wenn alles korrekt abläuft sollte im Erfolgsfall das Protokoll in etwa so aussehen:

Installing PHP SAPI module:       fpm
Installing PHP CLI binary:        /srv/php/bin/
Installing PHP CLI man page:      /srv/php/man/man1/
Installing shared extensions:     /srv/php/lib/php/extensions/no-debug-non-zts-20090626/
Installing PHP FPM binary:        /srv/php/sbin/
Installing PHP FPM config:        /srv/php/etc/
Installing PHP FPM man page:      /srv/php/man/man1/
Installing build environment:     /srv/php/lib/php/build/
Installing header files:          /srv/php/include/php/
Installing helper programs:       /srv/php/bin/
  program: phpize
  program: php-config
Installing man pages:             /srv/php/man/man1/
  page: phpize.1
  page: php-config.1
Installing PEAR environment:      /srv/php/lib/php/
[PEAR] Archive_Tar    - installed: 1.3.7
[PEAR] Console_Getopt - installed: 1.2.3
[PEAR] Structures_Graph- installed: 1.0.3
[PEAR] XML_Util       - installed: 1.2.1
[PEAR] PEAR           - installed: 1.9.1
Wrote PEAR system config file at: /srv/php/etc/pear.conf
You may want to add: /srv/php/lib/php to your php.ini include_path
/usr/src/php-5.x.x/build/shtool install -c ext/phar/phar.phar /srv/php/bin
ln -s -f /srv/php/bin/phar.phar /srv/php/bin/phar
Installing PDO headers:          /srv/php/include/php/ext/pdo/

Auch hier bereiten wir uns auf kommende Upgrades und Updates der Quellen vor und verschieben das Installationsverzeichnis und linken es zurück.

cd /usr/local/
mv php php-5.x.x
ln -s php-5.x.x php

Des Weiteren startet (oder auch nicht) unser PHP im Moment mit der Standardkonfiguration. Eine php.ini wird während der Installation nicht angelegt.

cd /srv/php/etc
touch php.ini
mkdir {fpm,php}.d

An dieser Stelle wird eine leere php.ini erstellt in der die Direktiven eingetragen werden können, die benötigt werden. Ansonsten startet PHP mit den Default-Werten. Dieser Maßnahme liegt zugrunde, dass eine Standard-php.ini den Start von PHP-FPM verhinderte.

Hier ein Auszug, der bereits in nachfolgendem Kapitel von Vorteil ist:

[Date]
date.timezone=Europe/Berlin
 
[zend]
zend_extension=/srv/php/lib/ZendExtensionManager.so
; The default level is usually set to 1, which includes very important information
; messages, errors and warnings.
zend_extension_manager.log_verbosity_level=2

; Scan for advanced zend configuration files
zend.conf_dir=/srv/php/etc
zend.ini_scandir=zend.d
zend_extension_manager.load_order_file=zem_order
zend_extension_manager.activate_signal_handlers=1

Connected?

Der Vollständigkeit halber sei hier noch die Beispielkonfiguration eines PHP-FPM Pools erwähnt. Diese definiert den PHP Prozess, der entweder an einem Socket lauscht, oder aber PHP über IP erreichbar macht. (Gegebenenfalls sind nachfolgende Pfad-Änderungen notwendig!)

[pool-name]

;listen = 127.0.0.1:9000
listen = /var/lib/php5/sockets/pool-name.socket
;listen.backlog = -1
 
listen.allowed_clients = 127.0.0.1
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
 
user = www-data
group = www-data
 
pm = dynamic
pm.max_children = 50
pm.start_servers = 15
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
;pm.status_path = /status

;ping.path = /ping
;ping.response = pong

;request_terminate_timeout = 0
;request_slowlog_timeout = 0
 
slowlog = /usr/local/php/var/log/pool-name.log.slow

;rlimit_files = 1024
;rlimit_core = 0

;chroot =
chdir = /
;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_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f y@ou.tld
php_flag[display_errors] = off
php_admin_value[error_log] = /usr/local/php/var/log/fpm-php.pool-name.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 128M
php_admin_value[apc.shm_size] = 64M

Die Verbindung zwischen PHP-FPM und NginX, in seiner einfachsten Form geschieht in der Nginx Konfiguration. Dazu wird ein upstream-Container definiert und diesem ein beliebiger Name (hier ‚php_backend‘) zugewiesen.

upstream php_backend {
        server unix:/tmp/php-cgi.socket;
        server 127.0.0.1:9000;
}

Connected!

Auf den upstream wird dann innerhalb eines server-Containers referenziert. In der Regel geschieht dies in verbindung mit PHP-FPM wie folgt:

   ...
   location ~ \.php$ {
     ...
     fastcgi_pass php_backend;
     ...
   }
   ...

AFTERLIFE

Im Afterlife wird PHP den eigenen Wünschen entsprechend angepasst, Module nachinstalliert und erweitert. Dabei handelt es sich primär um Module die die Auslieferung von PHP-Programmen beschleunigen. Die Übersetzung der Module referenziert auf pecl. Außer es befindet sich bereits eine Distributionsversion von PHP auf dem System wird das Übersetzen fehl schlagen. Um mit der aktuellen pecl-Version zu arbeiten passen wir unser User-Profil an.

#Updatehinweis

vi .profile

PATH="$PATH:/srv/php/bin"

memcache

Memcache beschleunigt PHP durch das Cachen von gleichen Anfragen.

pecl install memcache
Build process completed successfully
Installing '/srv/php/lib/php/extensions/no-debug-non-zts-20090626/memcache.so'
install ok: channel://pecl.php.net/memcache-2.2.6
configuration option "php_ini" is not set to php.ini location
You should add "extension=memcache.so" to php.ini

Aktivierung von memcache erfolgt in der Konfgurationsdatei von PHP im Speziellen durch die Angabe des Pfades:

vi /srv/php/etc/php.d/memcache.ini

extension=memcache.so

apc

APC beschleunigt PHP durch das Cachen von gleichen Anfragen.

pecl install apc
Build process completed successfully
Installing '/srv/php/lib/php/extensions/no-debug-non-zts-20090626/apc.so'
install ok: channel://pecl.php.net/APC-3.1.6
configuration option "php_ini" is not set to php.ini location
You should add "extension=apc.so" to php.ini

Aktivierung:

vi /srv/php/etc/php.d/apc.ini

extension=apc.so

pecl_http

pecl install pecl_http

Aktivierung:

vi /srv/php/etc/php.d/http.ini

extension=http.so

eAccelerator

Auch eAccelerator beschleunigt die Auslieferung von Anfragen.

wget http://bart.eaccelerator.net/source/0.9.6.1/eaccelerator-0.9.6.1.tar.bz2
tar xvf eaccelerator-0.9.6.1.tar.bz2
cd eaccelerator-0.9.6.1
phpize
./configure
make
make install

Im Gegensatz zu den anderen Extensions hat eAccelerator eine Vielzahl an Direktiven:

vi /srv/php/etc/php.d/eaccelerator.ini

extension="eaccelerator.so"
eaccelerator.shm_size="16"
eaccelerator.cache_dir="/tmp/eaccelerator"
eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="1"
eaccelerator.debug="0"
eaccelerator.filter=""
eaccelerator.shm_max="0"
eaccelerator.shm_ttl="0"
eaccelerator.shm_prune_period="0"
eaccelerator.shm_only="0"
eaccelerator.compress="1"
eaccelerator.compress_level="9"

ZendOptimizerPlus

Die Vorgehensweise für den ZendOptimizerPlus (und damit verbunden auch andere PHP-Zend Extensions wie bspw. den Debugger) ist, zunächst die Lib aus dem ZendServer (CE) zu extrahieren und anschließend als optimizerplus.ini zur Laufzeit zu laden. Allerdings schließt die Verwendung von ZendOptimizerPlus die Verwendung von eAccelerator aus. Der Server lässt sich zwar fehlerfrei starten, beim Aufruf einer PHP Seite kommt es allerdings zu einem 503.

Hinweis

Der ZendServer (CE) muss für die Extrahierung nicht installiert werden. Stattdessen installiert man zunächst 7zip.

apt-get install p7zip-full

Im Anschluss lädt man dann den ZendServer (CE) herunter. Ist ‚lynx‘ auf dem Server installiert, lässt sich dieser für den Download verwenden. Auf der Downloadseite des ZCE den Link extrahieren. Zum Zeitpunkt dieser Anleitung lautete dieser: http://www.zend.com/download/352?start=true. Lynx fordert zunächst zum Akzeptieren eines Cookies auf, was mit Y bestätigt wird. Mit D wird danach der Download bestätigt: application/x-gzip D)ownload, or C)ancel. Soweit man davon sprechen kann öffnet sich der Download-Dialog in lynx. Mit TAB auf ‚Save to disk‘ springen und mit ENTER bestätigen. Lynx bittet letztlich zur Eingabe des Dateinamens, der übernommen und ebenfalls mit ENTER bestätigt werden kann.

#Updatehinweis

tar xvf ZendServer-CE-php-5.3.3-5.0.4-linux-glibc23-i386.tar.gz
cd ZendServer-5.0.4_Tarball_B6-php5.3.3-linux-glibc23-i386
7z x -y zend.7z
cd zend

Unter /path/to/zend/lib befinden sich die relevanten Bibliotheken die wir Zu PHP hinzufügen:

cp -rp {ZendExtensionManager.so,optimizerplus,datacache,debugger,utils} /srv/php/lib/

vi optimizerplus.ini

zend_extension=/srv/php/lib/optimizerplus/php-5.3.x/ZendOptimizerPlus.so
zend_optimizerplus.enable=1
zend_optimizerplus.use_cwd=1
zend_optimizerplus.validate_timestamps=1
zend_optimizerplus.revalidate_freq=2
zend_optimizerplus.revalidate_path=0
zend_optimizerplus.log_verbosity_level=1
zend_optimizerplus.memory_consumption=64
zend_optimizerplus.max_accelerated_files=2000
zend_optimizerplus.max_wasted_percentage=5
zend_optimizerplus.consistency_checks=0
zend_optimizerplus.force_restart_timeout=180
zend_optimizerplus.blacklist_filename=
zend_optimizerplus.fast_shutdown=0
zend_optimizerplus.optimization_level=0xfffffbbf
zend_optimizerplus.enable_slow_optimizations=1

Weitere Informationen zum Optimizer Plus

http://files.zend.com/help/Zend-Server-Community-Edition/zendoptimizerplus.html

ZEM Order

Diese Datei gibt dem ZendExtensionManager vor in welcher Reihenfolge die einzelnen Zend Module zu starten sind. Installiert wird diese gemäß der Pfadangabe in der (rudimentären) php.ini (siehe oben).

datacache
optimizerplus
accelerator
debugger
debug_server

» Updatehinweise/Artikelhistorie

1.) Zum Zeitpunkt dieses Artikels gültige Versionen sollten durch ggf. aktuellere ersetzt werden. Ob dadurch die Kompatibilität gewährleistet werden kann ist zu prüfen und liegt in der Zuständigkeit des Lesers.

2.) Werden eAccelerator und ZendOptimizerPlus parallel aktiviert, startet der Webserver fehlerfrei. Diverse Anwendungen (u.a. WordPress) starten jedoch nicht.


3.) Beim Update von PHP kann es zu einem Fehler kommen mit einem Verweis auf die Ausführung von /srv/php/bin/phpize im Rootverzeichnis der zu installierenden Erweiterung (nacholgend). Dies ist dann der Fall, wenn eine inkompatible Version von phpize aufgerufen wird. zum Beispiel die Version der letzten Kompilierung.

FIX: phpize auf die aktuelle Version linken. Wer diesem Tutorial auch bei Updates folgt, der sollte diesen Schritt nur einmal machen müssen.

cp /usr/bin/pecl /usr/bin/pecl.bak
cp /usr/bin/pear /usr/bin/pear.bak  
 
ln -s /srv/php/bin/pecl /usr/bin/pecl
ln -s /srv/php/bin/pear /usr/bin/pear

4.) Entsprechend dem Betriebssystem kann es abweichend notwendig sein, das 64bit Packet des CE Servers zu laden.

5.) Wie in Kommentar 1 erwähnt kann das Hinzufügen bestimmter PHP-Erweiterungen es notwendig machen Systembibliotheken zu installieren. Bspw –with-curl macht es notwendig mittels apt weitere Bibliotheken zu installieren

apt-get install libltdl-dev libcurl4-openssl-dev

» Verwandte Themen

http://adminwerk.de/services/2011/nginx-ruby/

» Quellen und weiterführende Dokumentationen

» Howto, Nginx, PHP, PHP-FPM, Serverdienste, Ubuntu, Webserver » Nginx mit PHP-FPM [Update]
Im 6. Januar 2011
Von
, ,

Eine Antwort auf Nginx mit PHP-FPM [Update]

  1. chris sagt:

    Ein Hinweis sei noch angeführt.

    Bestimmte Module benötigen Bibliotheken. So sollte z.B. libcurl installiert sein wenn man cURL verwenden möchte. Der aufmerksame Leser sollte dies entsprechend berücksichtigen!

Schreibe einen Kommentar

« »

%d Bloggern gefällt das: