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.
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…
@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.