Настройка связки Nginx+Apache с PHP5, MySQL на Ubuntu

Unix

Автор: Александр Степанов

18 апр. 2013 г., 17:23:22  4272


На днях познакомился с одной интересной статьей и решил ее репостнуть на сайт. 

Источник: http://howitmake.ru/blog/ubuntu/42.html


Общая схема работы такая:

Все запросы приходят на сервер Nginx -он отдает статические данные (изображения (jpg, png, html и т.п.), далее он передает запрос на обработку скриптов WEB серверу Apache (PHP,cgi,pl и т.п.), скрипты выполняют запросы к MySQL и получив оттуда данные, возвращают их Nginx, тот, в свою очередь, отдает готовую страницу пользователям. Все просто. Данный мануал подходит для всех версий Ubuntu и Debian!

Установка Nginx

В репозиториях Ubuntu/Debian лежит старая версия пакета 0.7.65, ставить все из репозиториев и довольствоваться тем что есть, это для слабоков, мы соберем более свежую версию, для этого будем компилить исходники, в данный момент доступна версия nginx 1.0.4, ее мы и будем ставить.

Установка Nginx, поверх более старой версии
sudo su

Устанавливаем необходимые для компиляции пакеты и версию nginx из репозиториев:

apt-get install libpcre3-dev libcurl4-openssl-dev gcc nginx

Останавливаем демон:

/etc/init.d/nginx stop

Качаем исходники:

wget sysoev.ru/nginx/ и выбираем последную стабильную версию

Распаковываем:

tar -zxvf стабильный пакет

Переходим в директорию с распакованными исходниками:

cd стабильный пакет

Собираем и устанавливаем:

./configure --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --pid-path=/var/run/nginx.pid \
--user=www-data \
--group=www-data \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gzip_static_module \
--with-mail \
--with-mail_ssl_module
make
make install

Запускаем полученное:

/etc/init.d/nginx start

Переходим к настройке конфигурационного файла:

nano /etc/nginx/nginx.conf

 

user www-data;
worker_processes 2; #Обычно устанавливается по количеству ядер в процессоре

error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
# multi_accept on;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 64;
access_log /var/log/nginx/nginx.access.log;

proxy_buffers 8 16k;
proxy_buffer_size 32k;

sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;


gzip on; #Использование сжатия статики (Пример: CSS)
gzip_proxied any;
gzip_min_length 1100;
gzip_http_version 1.0;
gzip_buffers 4 8k;
gzip_comp_level 4; #Степень сжатия (больше ставить смысла нет, нагрузка на ЦПУ растет, а файлы меньше не практически становятся)
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Установка Apache-mpm-itk

Мы будем устанавливать Web сервер Apache, нам необходимо установить сборку Apache2-mpm-itk, ее отличие от обычной, заключается в возможности Apache, запускать виртуальные хосты сервера с правами разных пользователей, это позволяет, при грамотной расстановке прав доступа на директории, избежать перехода из корневой директории одного сайта в другую. Если кратко, то на обычной сборке apache все хосты работают от пользователя www-data, а эта, позволяет запускать от разных пользователей, не имеющих доступа в корневые директории соседей по серверу.

sudo su
aptitude install apache2-mpm-itk libapache2-mod-rpaf

Дожидаемся окончания установки, после завершения apache выдаст ошибку, такого содержания:

* Starting web server apache2 (98)Address already in use: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
Unable to open logs

Которая говорит нам о том, что 80й порт занят и он запуститься не может-это нормально, на восьмидесятом порту у нас висит nginx. Нам необходимо перенести Apache на другой порт, традиционно его переносят на порт 8080 (хотя можно на любой не занятый выше 1024го порта).

Для начала поправим порты:

nano /etc/apache2/ports.conf

По умолчанию там указано:

NameVirtualHost *:80
Listen 80

Мы делаем:

NameVirtualHost *:8080
Listen 127.0.0.1:8080

Во многих мануалах предлагается после переноса порта, зарубить к нему доступ через iptables-это НЕ правильно и является, по сути, костыльным решением. Для чего его блокировать, если можно совсем не выставлять, мы сделаем так, чтобы Apache начал принимать и обрабатывать запросы только от localhost и одновременно стал недоступным снаружи, вот по этому мы и добавляем в Listen 127.0.0.1:8080

Сделаем настройки, чтобы апач, меньше выдавал о себе информации

nano /etc/apache2/conf.d/security

Находим там строку:

ServerTokens OS

Меняем ее на:

ServerTokens Prod


Далее строку:

ServerSignature On

Меняем на:

ServerSignature Off

Сохраняем изменения, пробуем запустить Apache

/etc/init.d/apache2 start
Установка PHP5
apt-get install php5 libapache2-mod-php5 php5-mysql php5-snmp php5-gd php5-memcache php5-imagick php5-recode php5-xmlrpc php5-xsl php5-mcrypt php5-curl php-pear php5-imap
Устанавливаем MySQL
apt-get install mysql-server mysql-client

Указываем новый пароль и его подтверждение для пользователя root (это администратор MySQL, а не системный пользователь)

Настройка виртуального хоста Nginx

Теперь создадим первый виртуальный хост, для этого нам понадобится выполнить ряд действий:

  • 1-создать нового пользователя
  • 2-создать виртуальный хост Nginx
  • 3-создать виртуальный хост Apache

Создаем пользователя нашего тестового сайта example.org
sudo useradd example -b /home/ -m -U -s /bin/false

В домашней директории создадим каталоги для файлов сервера, логов и временных файлов.

sudo mkdir -p -m 754 /home/example/www
sudo mkdir -p -m 777 /home/example/tmp
sudo mkdir -p -m 754 /home/example/logs

Предоставим пользователю example права на эти директории:

sudo chown -R example: /home/example/www/
sudo chown -R example: /home/example/tmp/
sudo chown -R example: /home/example/logs/

Т.к. у нас Nginx работает от пользователя www-data, то он не сможет получить доступ к содержимому домашней директории пользователя example, но при создании была создана одноименная группа, в нее нам необходимо добавить пользователя www-data.

usermod -a -G example www-data

Таким образом, в будущем при создании нового виртуального хоста нам необходимо добавить пользователя www-data в группу с именем нового пользователя.

Основным симптомом что вы этого не сделали-отсутствие изображений на странице, которую вы запрашиваете с вашего сервера т.к. Nginx читает только графические файлы, то из-за отсутствия прав доступа к ним, он сделать этого не сможет, и страница генерируется без изображений-решение, добавить пользователя www-data (от имени которого работает Nginx) в одноименною группу пользоваться, от имени которого работает виртуальный хост Apache!

Лирическое отступление.
Если не добавить пользователя www-data в группу example, то после того, как любая CMS будет залита на сервер, сайт будет отображаться без графики (т.е. графические файлы выдаваться не будут, потому что не достаточно прав доступа). Для устранения этой проблемы необходимо добавить пользователя www-data в группу пользователя, от имени которого работает виртуальный хост и перезапустить nginx. Попробуйте на досуге, понимание этого приходит после первого коряво выглядящего дизайна ;) в дальнейшем вопросов не возникает.

Создаем виртуальный хост Nginx
sudo nano /etc/nginx/sites-available/example.org

И вставляем в него то, что указано ниже, в вашем случае пути необходимо указывать свои:

server {
listen 80;
server_name example.org www.example.org;
access_log /home/example/logs/nginx_access.log;
error_log /home/example/logs/nginx_error.log;
location ~* \.(jpg|jpeg|gif|png|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|tar|wav|bmp|rtf|swf|ico|flv|txt|docx|xlsx)$ {
root /home/example/www/;
index index.html index.php;
access_log off;
expires 30d;
}
location ~ /\.ht {
deny all;
}

location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
proxy_set_header Host $host;
proxy_connect_timeout 60;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_redirect off;
proxy_set_header Connection close;
proxy_pass_header Content-Type;
proxy_pass_header Content-Disposition;
proxy_pass_header Content-Length;
}
}

Сохраняем изменения и выходим. Теперь нам необходимо создать символическую ссылку, для того чтобы наш виртуальный хост заработал:

sudo ln -s /etc/nginx/sites-available/example.org /etc/nginx/sites-enabled/

И перезапустим Nginx:

sudo /etc/init.d/nginx restart
Настройки виртуального хоста Apache

sudo nano /etc/apache2/sites-available/example.org
<VirtualHost *:8080>
   DocumentRoot /home/example/www
   ServerAdmin [email protected]
   ServerName example.org
   ServerAlias www.example.org
   ErrorLog /home/example/logs/apache_error.log
   CustomLog /home/example/logs/apache_access.log combined
<Directory />
#Order Deny,Allow
#Deny from all
Options -ExecCGI -Indexes -Includes +FollowSymLinks
AllowOverride All
  <Limit GET POST>
  Order allow,deny
  Allow from all
  </Limit>
  <LimitExcept GET POST>
  Order deny,allow
  Deny from all
  </LimitExcept>
</Directory>

AssignUserId www-data example

php_admin_value open_basedir "/home/example/:."
php_admin_value upload_tmp_dir "/home/example/tmp"
php_admin_value session.save_path "/home/example/tmp"
</VirtualHost>

Также создадим символическую ссылку на файл example.org

sudo ln -s /etc/apache2/sites-available/example.org /etc/apache2/sites-enabled/

Перезапустим Apache:

/etc/init.d/apache2 restart

Теперь нам необходимо проверить работоспособность сервера, создадим в корневой директории сайта файл test.php с содержимым:

<?php phpinfo(); ?>

В окне должно быть все нормально)