Wprawdzie będzie to kompleksowy poradnik jak na czystym Debianie (np. w DigitalOcean) w kilka minut postawić serwer WWW na webserwerze Nginx z obsługą PHP (PHP5-FPM) – to proponuje też zapoznać się z tym wpisem, gdzie zostało szczegółowo omówiona instalacja pozostałych komponentów serwera WWW (m.in. MySQL, phpMyAdmin), które zapewne też się przydadzą.
Spis treści w artykule
Nginx i PHP5-FPM
Jak zawsze zaczynamy od aktualizacji systemu, po której przystępujemy do instalacji i konfiguracji webserwera Nginx oraz PHP-FPM.
Instalujemy Nginx i PHP5-FPM
sudo apt-get update
sudo apt-get install nginx
sudo apt-get install php5 php5-fpm php5-common php5-curl php5-mcrypt php5-gd php-gettext
Po udanej instalacji teoretycznie mamy już gotowy (web)serwer z obsługą plików PHP, choć przed nami jeszcze niezbędna konfiguracja…
Zawsze najnowsza wersja Nginx
Wprawdzie Nginx jest dostępny w systemie Debian w systemowych repozytoriach, to czasem korzystam z „firmowych repozytoriów” Nginx, dzięki czemu mam zawsze najnowszą wersję webserwera w systemie.
Przed instalacją samego Nginx edytujemy plik:
sudo nano /etc/apt/sources.list
I dodajemy 2 linijki/wpisy:
deb http://nginx.org/packages/mainline/debian/ WERSJA_SYSTEMU nginx
deb-src http://nginx.org/packages/mainline/debian/WERSJA_SYSTEMU nginx
Zamiast „WERSJA_SYSTEMU” wstawiamy nazwę wersji z której korzystamy, np. wheezy lub jessie.
Na koniec musimy jeszcze dodać niezbędne klucze:
wget http://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
Musicie mieć świadomość, że w przypadku „dużo nowszych wersji” Nginx konfiguracja może całkiem inaczej…
Konfiguracja Nginx i PHP5-FPM
Po instalacji Nginxa przechodzimy do edycji domyślnego pliku strefy WWW:
sudo nano /etc/nginx/sites-available/default
Minimalna konfiguracja dla plików strony w katalogu:
- /var/www/public_html/
wygląda tak:
server {
listen 80; ## listen for ipv4; this line is default and implied
#listen [::]:80 default_server ipv6only=on; ## listen for ipv6
root /var/www/[DOMENA]/public_html/;
index index.html index.htm index.php;
server_name localhost [DOMENA] *.[DOMENA];
location / {
try_files $uri $uri/ /index.php?$args;
}
access_log /var/log/nginx/[DOMENA]_access.log;
error_log /var/log/nginx/[DOMENA]_error.log;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# PHP5-FPM:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
# Nginx 1.2.1:
#include fastcgi_params;
# Nginx 1.6.1+:
include fastcgi.conf;
# Więcej informacji w tabelce poniżej
}
# deny access to .htaccess files (Apache2)
location ~ /\. {
deny all;
}
}
Biały ekran śmierci PHP
Może się zdarzyć, że po instalacji Nginx i PHP-FPM niby wszystko będzie działać, strony statyczne (zwykły HTML) będą się otwierać, ale próba otworzenia dowolnej strony PHP skończy się białym ekranem. By sprawę jeszcze bardziej skomplikować – pewnie nie będzie w logach żadnych istotnych/pomocnych wpisów.
Jest duża szansa, że wynika to z tego, że m.in. ten wpis powstał na przykładzie Nginx w wersji 1.2.1, który instalował się domyślnie w stabilnej wersji Debian 7 Wheezy. W Debian 8 Jessie domyślnie instaluje się Nginx w wersji 1.6.1 lub nowszej, a to wymaga drobnej modyfikacji konfiguracji.
Wersję webserwera Nginx sprawdzicie np. poleceniem:
patryk@rpi01 ~ $ sudo nginx -v
nginx version: nginx/1.6.2
Z racji tego, że cały czas można spotkać VPSy pracujące/korzystające z systemu Debian 7 postanowiłem zaktualizować wpis o ustawienia dla Nginx w wersji 1.6.1+, ale jednocześnie pozostawiając wpis dotyczący Nginx w wersji 1.2.1 (trzeba go ew odkomentować, a zakomentować ten dla 1.6.1+):
# Nginx 1.2.1:
#include fastcgi_params;
# Nginx 1.6.1+:
include fastcgi.conf;
Alternatywną (do wyboru opartego na wersji Nginx) metodą wyboru odpowiedniego wpisu może być skorzystanie z polecenia:
sudo ls /etc/nginx | grep "fastcgi"
Jeśli w odpowiedzi znajdziemy plik „fastcgi.conf”, to korzystamy z wpisu dla Nginx 1.6.1+, jeśli plik „fastcgi_params” – wersji dla Nginx 1.2.1.
Teraz szybki test, czy wszystko jest ok:
sudo /etc/init.d/nginx configtest
Jeśli tak – restart serwera:
sudo /etc/init.d/nginx restart
lub (preferuje) odświeżenie ustawień:
sudo /etc/init.d/nginx reload
Nginx obsługuje wszystkie pliki statyczne, a żądania PHP przekazuje do PHP5-FPM.
Kilka dodatkowych zabezpieczeń
Warto jeszcze rozważyć dodanie parametru „open_basedir” do naszej konfiguracji, dzięki czemu wszystkie (nie tylko) złośliwe skrypty będą ograniczone do katalogu domowego, a tym samym minimalizujemy szansę dostępu do plików innej strony, czy też odczytu konfiguracji całego serwera (np. katalog /etc/):
location ~ \.php$ {
[...]
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root";
[...]
}
Lub wersja z dostępem również do katalogu „/tmp”, by działało wgrywanie plików w PHP:
fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/tmp";
Oprócz tego warto zapoznać się z „safe_mode” (tryb bezpieczny) oraz „disable_finctions” (wyłączenie wybranych funkcji).
Połączenie szyfrowane, czyli obsługa SSL
Jeśli chcesz dodać do swojej strony obsługę połączeń szyfrowanych (HTTPS) to potrzebny Ci będzie certyfikat SSL. Informacje jak go przygotować najdziesz w wcześniejszych wpisach:
Różnica polega na tym, że konfigurację robimy dalej w plikach Nginxa, a nie Apache2:
sudo nano /etc/nginx/sites-available/default
I poniżej danych dla „normalnego połączenia” dodajemy:
# HTTPS server
server {
listen 443;
root /var/www/public_html/;
index index.html index.htm index.php;
server_name localhost [nazwa domeny] *.[nazwa domeny] 127.0.0.1;
access_log /var/log/nginx/default_ssl_access.log;
error_log /var/log/nginx/default_ssl_error.log;
ssl on;
# Dla własnego certyfikatu "odkomentuj" (usuń #) te 2 linie:
#ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
#ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
# Dla komercyjnego certyfikatu "odkomentuj" (usuń #) te 2 linie:
#ssl_certificate /katalog/z/certyfikatem/ssl.crt;
#ssl_certificate_key /katalog/z/certyfikatem/ssl.key;
# i zmień "/katalog/z/certyfikatem" na odpowiednią ścieżkę do certyfikatu
ssl_session_timeout 5m;
keepalive_timeout 60;
ssl_protocols TLSv1.1 TLSv1.2;
#ALT:
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
ssl_prefer_server_ciphers on;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# PHP5-FPM:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
# Nginx 1.2.1:
#include fastcgi_params;
# Nginx 1.6.1+:
include fastcgi.conf;
# Więcej informacji w tabelce powyżej
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /\. {
deny all;
}
}
Wspólna konfiguracja HTTP i HTTPS (SSL)
W przypadku gdy konfiguracja strony zarówno dla połączenia szyfrowanego jak i nieszyfrowanego jest identyczna – można sobie całą operację uprościć, i do konfiguracji dla połączenia nieszyfrowanego dodać:
listen 443 ssl;
ssl on;
# Dla własnego certyfikatu "odkomentuj" (usuń #) te 2 linie:
#ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
#ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
# Dla komercyjnego certyfikatu "odkomentuj" (usuń #) te 2 linie:
#ssl_certificate /katalog/z/certyfikatem/ssl.crt;
#ssl_certificate_key /katalog/z/certyfikatem/ssl.key;
# i zmień "/katalog/z/certyfikatem" na odpowiednią ścieżkę do certyfikatu
ssl_session_timeout 10m;
keepalive_timeout 60;
ssl_protocols TLSv1.1 TLSv1.2;
#ALT:
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
ssl_prefer_server_ciphers on;
zaraz poniżej
listen 80;
Teraz szybki test, czy wszystko jest ok:
sudo /etc/init.d/nginx configtest
Jeśli tak – restart serwera:
sudo /etc/init.d/nginx restart
lub (preferuje) odświeżenie ustawień:
sudo /etc/init.d/nginx reload
Dodatkowe domeny
Domeny dodajemy – podobnie jak w przypadku serwera Apache2 – przez utworzenie nowego pliku vHosta (sites-available) i jego aktywację (skrót w sites-enabled).
Najlepiej zacząć od kopii już istniejącego pliku:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/[nazwa domeny]
I następnie edycję pliku:
sudo nano /etc/nginx/sites-available/[nazwa domeny]
Gdzie wystarczy podmienić 2 linijki:
root /var/www/public_html/;
server_name localhost [nazwa domeny] *.[nazwa domeny] 127.0.0.1;
na:
root /var/www/[nazwa domeny]/public_html/;
server_name [nazwa domeny];
Warto też ustawić oddzielne pliki logów, modyfikując nazwy plików przy:
- access_log
- error_log
Po czym aktywujemy daną konfiguracje poleceniem:
sudo ln -s /etc/nginx/sites-available/[nazwa domeny] /etc/nginx/sites-enabled/[nazwa domeny]
Teraz szybki test, czy wszystko jest ok:
sudo /etc/init.d/nginx configtest
Jeśli tak – restart serwera:
sudo /etc/init.d/nginx restart
lub (preferuje) odświeżenie ustawień:
sudo /etc/init.d/nginx reload
Główny plik konfiguracyjny Nginx (nginx.conf)
Warto jeszcze chwile poświęcić dla pliku nginx.conf:
sudo nano /etc/nginx/nginx.conf
I tu dodajemy lub zmieniamy:
events {
worker_connections 1024;
multi_accept on;
}
Ukrywamy też informacje o serwerze:
http {
[...]
server_tokens off;
ignore_invalid_headers on;
reset_timedout_connection on;
[...]
}
Oraz jeszcze 2 modyfikacje, o których już kiedyś pisałem:
server_names_hash_bucket_size 256;
client_max_body_size 512M;
Nginx i WordPress
W przypadku gdy korzystamy z bardziej rozbudowanych CMSów, jak np. WordPress – zapewne będzie potrzebna jeszcze jedna modyfikacja w pliku strony:
sudo nano /etc/nginx/sites-available/default
Gdzie zmieniamy:
location / {
try_files $uri $uri/ /index.html;
}
na:
location / {
try_files $uri $uri/ /index.php?$args;
}
MySQL i phpMyAdmin
Cała procedura instalacji serwera SQL (MySQL) jak i phpMyAdmin jest identyczna jak w przypadku serwera na Apache2, tylko do pliku danej domeny (vHosta):
sudo nano /etc/nginx/sites-available/default
Dodajemy:
location /phpmyadmin {
root /usr/share/;
index index.php index.html index.htm;
auth_basic "STOP";
auth_basic_user_file /var/www/.passwords/.htpasswd;
location ~ ^/phpmyadmin/(.+\.php)$ {
try_files $uri =404;
root /usr/share/;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
# Nginx 1.2.1:
#include fastcgi_params;
# Nginx 1.6.1+:
include fastcgi.conf;
# Więcej informacji w tabelce powyżej
}
location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
root /usr/share/;
}
location /phpMyAdmin {
rewrite ^/* /phpmyadmin last;
}
}
I oczywiście:
sudo /etc/init.d/nginx configtest
sudo /etc/init.d/nginx restart
lub
sudo /etc/init.d/nginx configtest
sudo /etc/init.d/nginx reload
Testujemy czy serwer działa
Wprawdzie można przetestować serwer dowolną stroną, ale można też za pomocą pliku phpinfo.php:
<?php
phpinfo();
?>
Który otwieramy w przeglądarce, i zobaczymy zapewne coś takiego:
PS. Wpis przeleżał kilka miesięcy w oczekiwaniu aż ktoś wciśnie przycisk „publikuj”, ale wyszło mu to chyba tylko na dobre – przy okazji innych wpisów/poradników (zarówno tych opublikowanych, jak i tych które czekają na swoją kolej) czy projektów które w międzyczasie wykonywałem zawsze coś tam się jeszcze dopisało/zmodyfikował… :-)
- Wakacje składkowe ZUS a zawieszenie działalności gospodarczej, czyli uważaj, bo być może nie będziesz mógł skorzystać (w 2024) - 1970-01-01
- Przykładowy kalkulator wyceny usługi druku 3D, czyli nie tylko materiał się liczy - 1970-01-01
- Home Assistant 2024.10, czyli nowa karta „nagłówek” i niedziałający TTS w ramach usługi Google Cloud - 1970-01-01
@Patryk „następnym razem” prośba o solidne formatowanie wstawianych konfigów.
Chodzi o wcięcia? Staram się, ale niestety nawet duet pre+code w WordPressie potrafi je zgubić, nie tylko przy „oznaczaniu” czy wklejaniu, ale też np. przy późniejszej aktualizacji artykułu. Kiedyś testowałem do tego wtyczki, ale… z nimi też różnie. A do tego mechanizm ten bardzo, ale to bardzo nie lubi pustych linii, i nawet to wymaga zawsze kombinowania.
Ale skoro już przy tym jestem, to na szybko skorygowałem, nawet jeśli jest to stary poradnik i w planach jest jego odświeżenie (trochę się przez ten okres pozmieniało). Co nawet wyszło na dobre, bo nie wiem, czy w jednym miejscu „wąsaty nawias” nie przeskoczył tam, gdzie nie trzeba… ;-)