Seit einigen Tagen habe ich einen neuen Root-Server, der meine Webseite ausliefern soll. Da ich ein bisschen experimentierfreudig bin, habe ich mich zur Installation des Webservers nginx (sprich engine-x) entschlossen, da dieser in vielen Benchmarks noch schneller als lighttpd ist und gleichzeitig weniger RAM verbraucht.

Gleichzeitig sind aber die Rewrite-rules einfacher als beim lighttpd, da diese fast 1:1 vom Apache zu übernehmen sind (was den Umzug der Seiten deutlich einfacher gestaltet). Ich möchte direkt nativ alles über nginx und dessen FastCGI-Backend ausliefern, weshalb ein paar zusätzliche Artikel zu deren Rewrite-Rules oder Stolperfallen bei der Einrichtung kommen werden.

Dieser Artikel ist Teil einer Reihe zum Webserver nginx. Schau dir auch die anderen Artikel an: Zum Leitartikel

Los geht’s mit der Installation von Gentoo, welche ich nach Handbuch durchführe. Hierzu verliere ich keine weiteren Worte, da das Handbuch wirklich umfangreich und ausreichend ist. Wichtig ist, dass Portage auf dem aktuellen Stand ist, das sollte aber nach der Installation der Fall sein.

Ich wollte den nginx mit den zusätzlichen Modulen FastCGI, PCRE, SSL, Stub_Status, WebDAV und zlib, weshalb ich die folgenden USE-Flags hinzugefügt und anschließend den nginx installiert habe:

1
2
echo "www-servers/nginx fastcgi pcre ssl status webdav zlib" >> /etc/portage/package.use
emerge -av nginx

Zum Zeitpunkt des Schreibens wird Version 0.7.61 installiert.

Nach dem emergen von Nginx kommt bei mir die Konfiguration von PHP. Ich fahre schon seit Ewigkeiten mod_fcgid unter Apache, welcher die Verwaltung (Starten/Stoppen/Steuerung) der PHP-Prozesse selbst übernimmt. Bei nginx wird das etwas anders angesteuert, da die PHP-Prozesse schon existieren müssen und nginx diese nicht selbst erstellt. Um dies zu vereinfachen, gibt es das Project spawn-fcgi, welches aus dem Webserverprojekt lighttpd ausgegliedert wurde.

Zum Zeitpunkt dieses Tutorials ist dieses Paket in Gentoo noch nicht als stable gekennzeichnet, weshalb man es vor der Installation möglicherweise erst freischalten muss:

1
2
echo "www-servers/spawn-fcgi" >> /etc/portage/package.keywords
emerge -av spawn-fcgi

Jetzt sollte man sich ein paar Gedanken zur Aufteilung der Webserverhosts über die PHP-Prozesse machen. Dazu muss man ein wenig Hintergrund zur FastCGI-Technologie kennen. Zur Verarbeitung der PHP-Seiten wird ein PHP-Interpreter gestartet mit dem der Webserver über einen Unix-Socket oder einen TCP-Port kommuniziert. Diese Interpreter kann man unter einem anderen Nutzer (als root) starten, wodurch ein wenig zusätzliche Sicherheit geschafft wird, wenn dieser Nutzer weniger Rechte hat. Im Idealfall sollte man also für jeden Vhost einen eigenen PHP-Interpreter und Nutzer haben, um die höchste Sicherheit zu erhalten. Leider benötigt jeder Interpreter ein wenig RAM, sodass man sich überlegen sollte, wieviele man davon gleichzeitig im RAM halten möchte. Ich habe für mich einen Mix aus Performance und Sicherheit gewählt. Ich zeige mal an einem Vhost, wie man diese PHP-Interpreter startet.

Startet man nun /etc/init.d/spawn-fcgi, so wird man ermahnt, dass das so nicht funktioniert:

  • You are not supposed to run this script directly. Create a symlink
  • for the FastCGI application you want to run as well as a copy
  • of the configuration file and modify it appropriately like so…
  • ln -s spawn-fcgi /etc/init.d/spawn-fcgi.trac
  • cp /etc/conf.d/spawn-fcgi /etc/conf.d/spawn-fcgi.trac
  • nano /etc/conf.d/spawn-fcgi.trac

Folglich führe ich diese Schritte für meinen ersten FastCGI-Server durch:

1
2
ln -s spawn-fcgi /etc/init.d/spawn-fcgi.wolfuli
cp /etc/conf.d/spawn-fcgi /etc/conf.d/spawn-fcgi.wolfuli

Jetzt muss man die Konfigurationsdatei /etc/conf.d/spawn-fcgi.wolfuli editieren:

FCGI_SOCKET= FCGI_ADDRESS=127.0.0.1 FCGI_PORT=1234 FCGI_PROGRAM=/usr/bin/php-cgi FCGI_CHILDREN=1 FCGI_CHROOT= FCGI_CHDIR= FCGI_USER=wolfuli FCGI_GROUP=wolfuli PHPRC="/var/www/php-ini/wolfuli/" PHP_FCGI_CHILDREN=10 PHP_FCGI_MAX_REQUESTS=1000 ALLOWED_ENV="PATH PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS PHPRC"

Über die Variable PHPRC wurde ein Verzeichnis festgelegt, in dem man man eine, für den Vhost angepasste, php.ini hinterlegen kann.

Jetzt muss man noch den Nutzer wolfuli samt der gleichen Nutzergruppe anlegen:

1
useradd -s /bin/false -U wolfuli

Jetzt richten wir mal unsere Vhosts ein. Aus praktischen Gründen habe ich mich entschlossen ein “sites-available” und ein “sites-enabled”-Verzeichnis anzulegen.

1
2
mkdir /etc/nginx/sites-available
mkdir /etc/nginx/sites-enabled

So kann ich Vhosts im ordner sites-available konfigurieren und dann diese dann in sites-enabled softlinken, wenn sie aktiv sein sollen. So kann ich mal vhosts abschalten ohne diese gleich löschen zu müssen.

Die /etc/nginx/nginx.conf habe ich ebenfalls ein wenig abgeändert, sodass diese wie folgt aussieht:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
user nginx nginx;
worker_processes 2;
error_log /var/log/nginx/error_log info;
events {
 worker_connections 8192;
 use epoll;
}
http {
 include /etc/nginx/mime.types;
 default_type application/octet-stream;
 log_format main
 '$remote_addr - $remote_user [$time_local] '
 '"$request" $status $bytes_sent '
 '"$http_referer" "$http_user_agent" '
 '"$gzip_ratio"';

 client_header_timeout 10m;
 client_body_timeout 10m;
 send_timeout 10m;
 connection_pool_size 256;
 client_header_buffer_size 1k;
 large_client_header_buffers 4 2k;
 request_pool_size 4k;
 gzip on;
 gzip_min_length 1100;
 gzip_buffers 4 8k;
 gzip_types text/plain;
 output_buffers 1 32k;
 postpone_output 1460;
 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_timeout 75 20;
 ignore_invalid_headers on;
 index index.html;

 include /etc/nginx/sites-enabled/*;
}

Wie man sieht, ist nun in der letzten Zeile ein include aller Vhosts aus dem “sites-enabled"-Verzeichnis. Die Variable “worker_processes” sollte auf die Anzahl der CPU-Kerne gesetzt werden, was in meinem Falle zwei sind.

Damit ist die Installation abgeschlossen, jetzt kann man nun einen PHP-VHost anlegen. Dazu muss zunächst die Datei /etc/nginx/fastcgi_params angelegt bzw. modifiziert werden, sodass diese so aussieht:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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 SCRIPT_FILENAME $document_root$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 wolfuli/1337;

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;

fastcgi_index index.php;

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

Diese Datei legt einige Parameter im Zusammenspiel von PHP (FastCGI) und nginx fest.

Hier der Beispielvhost example.com, welcher unter /etc/nginx/sites-available/example.com angelegt wird:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
server {
 listen 80;
 server_name example.com;
 error_log /var/log/nginx/example.com.log warn;
 root /var/www/example.com/;

 location / {
 index index.php;
 }

 location ~ \.php$ {
 fastcgi_pass 127.0.0.1:1234;
 include /etc/nginx/fastcgi_params;
 }
}

Jetzt muss man den fertigen Vhost nur noch softlinken:

cd /etc/nginx/sites-enabled/ ln -s ../sites-available/example.com

Und nginx die neuen Konfigurationsdateien lesen lassen:

/etc/init.d/nginx reload

Das wars. Lies auch die anderen Artikel zu diesem Thema in diesem Leitartikel.