Serwer na Debianie: nginx, PHP i bazy danych

Przedstawiam mój przepis szybkie postawienie serwera, na którym działa nginx, PHP i bazy danych. Ja z powodzeniem używam takiej konfiguracji na maszynie deweloperskiej, ale można jej też użyć jako punktu wyjścia do konfiguracji serwera produkcyjnego, jednak w tym wypadku radzę uważnie przeczytać zastrzeżenia na końcu.

W przepisie używam Debiana Squeeze, ale po dodaniu sudo przed większością poleceń będzie go można zastosować do Ubuntu. ;-)

Opisywana konfiguracja spełnia następujące założenia:

  • Na serwerze mają działać nginx, PHP, MySQL, PostgreSQL, MongoDB i memcached.
  • Oprogramowanie powinno być w możliwie aktualnych stabilnych wersjach.
  • Skrypty PHP mają działać z prawami użytkownika.
  • Serwer powinien mieć możliwość uruchamiania skryptów PHP zabezpieczonych ionCube’em.

Przygotowania

Na początek ustawiamy locale na serwerze na pl_PL.UTF8 oraz konfigurujemy polecenie adduser tak, by użytkownicy nie mogli przeglądać zawartości katalogów domowych sąsiadów.

dpkg-reconfigure locales
dpkg-reconfigure adduser

Warto poszerzyć horyzonty apta o sekcje contrib i non-free, bo dzięki temu uzyskujemy dostęp do tak przydatnych narzędzi jak rar. W tym celu należy zmodyfikować /etc/apt/sources.list do postaci:

deb http://ftp.pl.debian.org/debian squeeze main contrib non-free
deb http://security.debian.org squeeze/updates main contrib non-free

Następnie warto zainstalować garść przydatnych pakietów:

aptitude install curl mc nano bash-completion htop iotop mtr-tiny bzip2 p7zip-full p7zip-rar rar unrar rsync screen telnet

PHP

Debian Squeeze ma w paczkach PHP w wersji 5.3, która już nie jest rozwijana. Obecną stabilną wersję 5.4 można pobrać z repozytorium dotdeb.org. Jego opiekun przygotowuje nowe paczki PHP przeważnie w odstępie tygodnia po opublikowaniu ich na php.net, dzięki czemu nasza instalacja będzie zawsze aktualna. Oprócz PHP z dotdeb.org można pobrać nginx’a, MySQL i kilka innych przydatnych pakietów. W /etc/apt/sources.list.d/dotdeb.list wpisujemy:

deb http://packages.dotdeb.org squeeze all
deb-src http://packages.dotdeb.org squeeze all
deb http://packages.dotdeb.org squeeze-php54 all
deb-src http://packages.dotdeb.org squeeze-php54 all

Następnie dodajemy klucz dla tego repozytorium:

curl http://www.dotdeb.org/dotdeb.gpg | apt-key add -

Teraz możemy już instalować pakiety. Nie wszystkie z wymienionych niżej pakietów są niezbędne, wedle własnego uznania można pominąć niepotrzebne pakiety, np. obsługę baz danych, których nie planujemy używać. Z kolei na serwerze deweloperskim warto dorzucić pakiet php5-xdebug.

aptitude update
aptitude install php-pear php5-dev php5 php5-apc php5-cli php5-curl php5-fpm php5-gd php5-intl php5-memcached php5-mcrypt php5-mysql php5-pgsql

W plikach /etc/php5/fpm/php.ini oraz /etc/php5/cli/php.ini należy odnaleźć opcje short_open_tag i date.timezone oraz zmienić ich wartości na podane poniżej.

short_open_tag = Off
date.timezone = Europe/Warsaw

W wypadku konfiguracji deweloperskiej warto włączyć pokazywanie błędów:

display_errors = On

Standardowa instalacja php5-fpm tworzy tylko pulę procesów działających z prawami użytkownika www-data. Jeśli chcemy mieć skrypty PHP wykonywane z prawami innych użytkowników należy utworzyć odpowiednie pule. Najprościej skopiować plik www.conf:

cp /etc/php5/fpm/pool.d/www.conf /etc/php5/fpm/pool.d/uzykownik.conf

a następnie zmienić w nim nazwę puli (w nawiasach kwadratowych na początku pliku) i parametry user, group oraz listen. Po okrojeniu ze nieużywanych opcji i komentarzy konfiguracja może wyglądać następująco:

[uzytkownik]

user = uzytkownik
group = uzytkownik

listen = /var/run/php5-fpm_uzytkownik.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

chdir = /

Lektura dodatkowa:

mongo

Jeśli chcemy cieszyć się obsługą MongoDB w PHP-ie należy stosowne rozszerzenie zbudować sobie samemu.

pecl install mongo

Uwaga: aby budować rozszerzenia ze źródeł niezbędne są pakiety php5-dev oraz php-pear.

Żeby poinformować PHP o istnieniu tego rozszerzenia należy utworzyć plik /etc/php5/mods-available/mongo.ini i wpisać do niego:

extension=mongo.so

Następnie należy go podlinkować do katalogu, z którego PHP czyta konfigurację:

ln -s /etc/php5/mods-available/mongo.ini /etc/php5/conf.d/20-mongo.ini

Poprawność instalacji możemy zweryfikować wpisując:

php -m | grep mongo

ionCube

Modułu dekodującego skrypty zabezpieczone ionCube’em nie ma w paczkach, ale instalacja i tak jest prosta. Należy pobrać archiwum ze strony producenta, rozpakować je i przenieść w odpowiednie miejsce:

wget http://downloads2.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.bz2
tar xvfj ioncube_loaders_lin_x86-64.tar.bz2
mv ioncube /usr/lib/php5/

Drugim krokiem jest dodanie modułu do konfiguracji PHP. W tym celu należy utworzyć plik /etc/php5/mods-available/ioncube.ini o następującej zawartości:

zend_extension=/usr/lib/php5/ioncube/ioncube_loader_lin_5.4.so

Oczywiście przy założeniu, że przy instalacji PHP wybraliśmy wersję 5.4. Ostatnim krokiem jest utworzenie dowiązania symbolicznego:

ln -s /etc/php5/mods-available/ioncube.ini /etc/php5/conf.d/30-ioncube.ini

PostgreSQL

PostgreSQL 9.2, czyli obecnie najświeżą wersję serwera, można znaleźć w repozytorium utrzymywanym przez PostgreSQL Global Development Group. By z niego skorzystać tworzymy plik /etc/apt/sources.list.d/pgdg.list o następującej treści:

deb http://apt.postgresql.org/pub/repos/apt/ squeeze-pgdg main

Dodajemy klucz dla powyższego repozytorium:

curl http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | apt-key add -

Następnie instalujemy właściwy pakiet:

aptitude update
aptitude install postgresql-9.2

Domyślnie wszyscy użytkownicy lokalni mają dostęp do swoich baz bez konieczności podawania hasła. Nie do końca mi to odpowiada, dlatego polecam w pliku /etc/postgresql/9.2/main/pg_hba.conf zmienić linię:

local   all             all                                     peer

na

local   all             all                                     md5

Lektura dodatkowa:

MySQL

Przy założeniu, że mamy dodane repozytorium dotdeb.org instalacja MySQL sprowadza się do wydania polecenia:

aptitude install mysql-server-5.5

W trakcie instalacji należy jedynie wybrać hasło roota, które warto zapamiętać.

MongoDB

Instalację MongoDB polecam uczynić z repozytorium producenta. Zatem tworzymy plik /etc/apt/sources.list.d/10gen.list o treści:

deb http://downloads-distro.mongodb.org/repo/debian-sysvinit dist 10gen

Następnie dodajemy klucz dla repozytorium i instalujemy właściwy pakiet:

apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
aptitude update
aptitude install mongodb-10gen

Po chwili serwer MongoDB już powinien działać. W wypadku maszyny deweloperskiej proponuję wprowadzić małe zmiany w konfiguracji, które ograniczą zapędy mongod do pożerania przestrzeni dyskowej. W pliku /etc/mongodb.conf wprowadzamy następujące zmiany:

noprealloc = true
smallfiles = true

Lektura dodatkowa:

memcached

Króka piłka:

aptitude install memcached

nginx

Częstokroć na serwerach domyślnie jest już zainstalowany Apache. Przed instalacją nginx’a można go usunąć:

aptitude purge apache2 apache2-doc apache2-mpm-prefork apache2.2-bin apache2.2-common

Celowo nie usunąłem pakietu apache2-utils, bo znajdujące się tam narzędzia, np. ab, przydają się nie tylko użytkownikom Apache’a.

Teraz można już przystąpić do instalacji nginx’a. Ponownie skorzystamy z repozytorium dotdeb.org ponieważ nie tylko zawiera tak samo aktualne wersje jak oficjalne repozytorium nginx’a, ale dodatkowo udostępnia kilka kompilacji serwera różniących się dostępnymi modułami. Zapewne w typowych zastosowania wystarczy pakiet nginx-light, ale na wszelki wypadek można od razu zainstalować nginx-full. W razie czego przejście z jednej kompilacji na inną jest bezproblemowe.

aptitude install nginx-full

WordPress

Mamy już wszystkie składniki potrzebne do serwowania stron napisanych w PHP, na próbę możemy zainstalować najpopularniejszą aplikację blogową czyli wordpressa. Zgodnie z instrukcją pobieramy i rozpakowujemy archiwum, po czym zmieniamy właściciela i grupę katalogu z aplikacją na www-data.

wget http://wordpress.org/latest.tar.gz
tar -xzvf latest.tar.gz
mv wordpress /var/www/wordpress.domena.pl
chown -R www-data:www-data /var/www/wordpress.domena.pl

Następnie logujemy się do bazy MySQL jako użytkownik root i tworzymy bazę i użytkownika dla naszego bloga:

CREATE DATABASE blog_wordpress CHARACTER SET utf8 COLLATE utf8_polish_ci;
GRANT ALL PRIVILEGES ON blog_wordpress.* TO 'blog'@'localhost' IDENTIFIED BY 'DobreHaslo';

Teraz tworzymy vhosta w konfiguracji nginx’a w pliku /etc/nginx/sites-available/wordpress.domena.pl:

server {
    server_name wordpress.domena.pl;
    root /var/www/wordpress;
    access_log /var/log/nginx/wordpress.domena.pl-access.log;
    error_log /var/log/nginx/wordpress.domena.pl-error.log;

    index index.php;
 
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }
 
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
 
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm_www.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }
}

Potem linkujemy plik do katalogu z aktywnymi vhostami:

ln -s /etc/nginx/sites-available/wordpress.domena.pl /etc/nginx/sites-enabled/wordpress.domena.pl

Po przeładowaniu konfiguracji nginx’a:

/etc/init.d/nginx reload

powinniśmy mieć już działającą stronę i możemy przejść do instalacji:

http://wordpress.domena.pl/wp-admin/install.php

Lektura dodatkowa:

Uwagi końcowe

Powyższa konfiguracja dobrze sprawdzi się na maszynie deweloperskiej, jednak byłbym ostrożny przed używaniem jej w środowisku produkcyjnym. Po pierwsze usługi trzeba skonfigurować pod konkretne zastosowania, dopasować rozmiary buforów, ustawić logowanie itd, ja zaś w opisie ograniczyłem się do niezbędnych zmian w domyślnych plikach konfiguracyjnych. Po drugie konfiguracja serwera to nie tylko nginx i MySQL, jest masa innych rzeczy, o które trzeba zadbać czy to ze względu na bezpieczeństwo (firewall, chroot) czy wydajność. Po trzecie uważam się za programistę, a nie administratora, więc jeśli wasz serwer ma służyć do czegoś ważnego to lepiej zatrudnijcie profesjonalistę.

Wydaje mi się, że powyższa konfiguracja jest niezła, ale jeśli gdzieś popełniłem błąd albo jeśli coś można zrobić lepiej to proszę o stosowne napomnienie w komentarzach.

2 komentarze do “Serwer na Debianie: nginx, PHP i bazy danych”

  1. Dzięki za fajny post. Ja zrobiłbym dodatkowo (jako admin:-)):
    Zamiast:
    /var/www/wordpress.domena.pl
    Dałbym:
    /var/www/wordpress.domena.pl/1.0
    W ten sposób w /1.0 masz aktualną wersję, a wersję 1.1 w np. /1.1.

    I zmieniłbym limit wielkości plików w PHP.INI:
    Po zmianie PHP.INI aby względnić zmiany:
    /etc/init.d/php5-fpm reload
    a następnie tak:
    /etc/init.d/nginx reload
    i nowe ustawienia zaczną działać:-)

    Co do bezpieczeństwa, to jeszcze sporo roboty – ale to inny wątek…

  2. @Informatyk Kraków
    Oddzielne katalogi na kolejne wersje to jest niezły pomysł, ale moim zdaniem warto się to bawić przy większych i ważniejszych instalacjach. W wypadku małego blogaska to armata na komara. Przy tym blogu początkowo robiłem kopię katalogu i bazy przed aktualizacją, ale nigdy żadne problemy nie wystąpiły, więc dałem sobie spokój. W razie draki mam automatycznie robiony backup nie starszy niż 24 godziny. Poza tym teraz WordPressa aktualizuje się przez panel, co jest o wiele szybsze i wygodniejsze niż ręczna aktualizacja plików.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *