Пошаговая настройка Apache с выбором версий php + Nginx как reverse proxy (с mod_pagespeed) на ubuntu 16.04

  • Tutorial
В интернете кучу статей по настройке сервера, настройки Apache, Nginx и т.п. В данной статье будет пошагово настроен простой shared хостинг. Все операции производятся через консоль.

В посте будут решены и описаны следующий задачи:

1. Установка Apache + PHP
2. Возможность выбора версий PHP
3. Возможность работы сайтов от разных пользователей, с ограничением на чтение директорий других сайтов.
4. Установка Nginx с модулем pagespeed от google
5. Настройка Nginx как reverse proxy

Все этапы будут содержать описание и пояснения. Сам пост писался больше для себя, чтобы не потерять порядок настройки, но будет очень полезным для новичков, которые начинают разбираться в администрировании сервера. В качестве сервера установлен Ubuntu 16.0.4 только с SSH.

ЭТАП 1 (Установка Apache + PHP)

Запускаем оболочку с root правами:

sudo -i

Устанавливаем apache:

apt install -y apache2

Ключ
 -y 
нужен для того чтобы в процессе установки, автоматически на все вопросы отвечал положительно. К примеру если выполнить:

 apt install apache2 

то в процессе установки нас спросят, действительно ли мы хотим установить.

Устанавливаем php (как mod_php)

 apt install -y php libapache2-mod-php 

На данном этапе у нас установиться php версии 7 как модуль apache.

ЭТАП 2 (Возможность выбора версий PHP)

На первом этапе мы установили сервер Apache + PHP при чем PHP у нас работает как модуль Apache. Существует несколько режимов работы PHP подробную информацию можно прочитать по ссылке «Коротко о CGI, FastCGI, PHP-FPM и mod_php».

Если вам лень читать, то объясню проще:

1. mod_php — сам Apache выполняет php скрипт.

Плюсы: работает быстро, требует минимум настроек и знаний
Минусы: скрипты выполняются от пользователя apache (как правило www-data)

2. CGI/FastCGI — Сервер Apache запускает прикладной скрипт интерпретатора php-cgi, который в свою очередь выполняет php скрипт

Плюсы: скрипты выполняются от произвольного пользователя, можно использовать в связке с другими приложениями (Nginx + PHP), конфигурацию PHP можно сделать индивидуальной
Минусы: скорость работы, дополнительная настройка

3.PHP-FPM — это модернизированный fast-cgi сервер который постоянно держит готовые для работы пул-процессов.

Плюсы: скорость работы, скрипты выполняются от произвольного пользователя, можно использовать в связке с другими приложениями (Nginx + PHP-FPM — самая распространная реализация)
Минусы: дополнительная настройка, занимает порт, на каждого пользователя открывается свой порт.

Мы остановимся на CGI/FastCGI. На самом деле многие может испугать, что он самый медленный, но на большинстве shared хостингов, именно этот режим работы (ispmanager использует именно этот режим работы). Нам потребуется собрать из исходников версии php которые нам необходимы.

2.1 Сборка php из исходников

Обновляем репозиторий:

apt update

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

apt install -y make \
git autoconf \
lynx \
wget \
build-essential \
libxml2-dev \
libssl-dev \
libbz2-dev \
libcurl4-openssl-dev \
libpng12-dev \
libfreetype6-dev \
libxpm-dev \
libmcrypt-dev \
libmhash-dev \
libmysqlclient-dev \
libjpeg62-dev \
freetds-dev \
libjson-c-dev \
re2c \
zlib1g-dev \
libpcre3 \
libpcre3-dev \
unzip \
libxslt1-dev

Символ \ используется как перенос строки, для удобства чтения.

Создаем папки для php:

mkdir -p /opt/source/php
mkdir -p /opt/php/

Переходим в директорию в которой будут храниться исходники php

cd /opt/source/php

Скачиваем необходимую версию php и распаковываем ёё:

wget -c http://php.net/get/php-5.6.18.tar.bz2/from/this/mirror -O php-5.6.18.tar.bz2
tar xvjf php-5.6.18.tar.bz2

В последней команде мы скачали по ссылке php-5.6.18 и сохранили как php-5.6.18.tar.bz2
После чего распаковали архив.

Переходим в директория скаченного и распакованного php

cd /opt/source/php/php-5.6.18

Конфигурируем php

./configure --enable-cli \
 --prefix=/opt/php/php-5.6.18		\
 --disable-rpath		\
 --enable-calendar		\
 --enable-discard-path 		\
 --enable-fastcgi		\
 --enable-force-cgi-redirect		\
 --enable-fpm		\
 --enable-ftp		\
 --enable-gd-native-ttf		\
 --enable-inline-optimization		\
 --enable-mbregex		\
 --enable-mbstring		\
 --enable-pcntl		\
 --enable-soap		\
 --enable-sockets		\
 --enable-sysvsem		\
 --enable-sysvshm		\
 --enable-zip		\
 --with-bz2		\
 --with-curl		\
 --with-curl 		\
 --with-freetype-dir		\
 --with-gd		\
 --with-gd 		\
 --with-gettext		\
 --with-jpeg-dir 		\
 --with-jpeg-dir=/usr/lib/		\
 --with-libdir=/lib/x86_64-linux-gnu		\
 --with-libxml-dir=/usr		\
 --with-mcrypt		\
 --with-mhash		\
 --with-mysql		\
 --with-mysql 		\
 --with-mysqli		\
 --with-mysqli 		\
 --with-openssl		\
 --with-pcre-regex		\
 --with-pdo-mysql		\
 --with-png-dir=/usr		\
 --with-zlib		\
 --with-zlib-dir

Стоить обратить внимание на строку --prefix=/opt/php/php-5.6.18. Именно в эту директорию будет собран проект. Также вы самостоятельно можете добавлять или удалять необходимые модуль и компоненты php. Но при конфигурации обязательно должны быть --enable-fastcgi и --enable-force-cgi-redirect. После конфигурации собираем php

make
make install

Процесс сборки непривычно долгий, поэтому не стоит переживать по этому поводу. По завершению сборки можно проверить командой:

/opt/php/php-5.6.18/bin/php -v

В результате будет что то вроде:

PHP 5.6.18 (cli) (built: Jun 8 2017 15:59:20)
Copyright © 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright © 1998-2016 Zend Technologies


2.2 Настройка Apache

Далее нам потребуется чтобы Apache вызывал php скрипт через режим fastcgi. Устанавливаем и активируем mod_fcgi

apt install libapache2-mod-fcgid
a2enmod cgi fcgid actions

перезапустим сервис Apache

service apache2 restart

2.3 Создание CGI скрипта

Создадим обертку для запуска PHP-FastCGI

mkdir -p /opt/php/php-5.6.18/fcgi-bin

В данной папке создадим скрипт с именем php со следующим содержимом
#!/opt/php/php-5.6.18/bin/php-cgi. Лично я использую редактор nano.

nano /opt/php/php-5.6.18/fcgi-bin/php

Вставляем код, выходим CTRL+X и подтверждаем изменения.

Делаем файл испольняемым:

chmod +x /opt/php/php-5.6.18/fcgi-bin/php

В той же директории создаем файл php.ini () можно скопировать /opt/source/php/php-5.6.18/php.ini-production.

2.4 Настройка хоста для Apache

В примере будет показана настройка виртуального хоста по умолчанию:

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        <IfModule mod_fcgid.c>
            IPCCommTimeout 7200
            FcgidConnectTimeout 320
            MaxRequestLen 25728640
            FcgidMaxRequestsPerProcess 0
            FcgidBusyTimeout 3600
            FcgidOutputBufferSize 0
        </IfModule>

        <FilesMatch "\.ph(p[3-5]?|tml)$">
                SetHandler fcgid-script
                FCGIWrapper /opt/php/php-5.6.18/fcgi-bin/php
        </FilesMatch>
        ErrorLog /var/www/html/error.log
        CustomLog /var/www/html/access.log combined
</VirtualHost>
<Directory /var/www/html>
        Options +Includes +ExecCGI
</Directory>

Перезапускаем настройки Apache:

service apache2 reload

ЭТАП 3 ( Возможность работы сайтов от разных пользователей, с ограничением на чтение директорий других сайтов.)

Для разграничения прав по пользователям у Apache есть 2 разных модуля suEXEC и ITK.

Рассмотрим как работает каждый из них:

ITK — При поступлении запроса, apache создает процесс-обработчик, который наследует права корневого процесса, но после проверки контекста меняет свои права на указанного пользователя.

suEXEC -При поступлении запроса apache запускает CGI и аналогичные собственные или сторонних разработчиков скрипты/программы внутри веб-папки домена от имени указанного пользователя.

suEXEC в нашем варианте предпочтительней из-за особенности архитектуры работы. Устанавливаем suEXEC

apt install apache2-suexec-custom
a2enmod suexec


Важно, для правильной работы suexec необходимы правильно выставить права на директории.
Как располагать директории вы должны определиться сами, в примере приведется пример, и он не является оптимальным.

Иерархия папок следующая:

|--/var/www/ - Корневая папка, права 751 владелец root
|----/php-bin - Папка храннения дефолтных настроек для php
|------/php-5.6.18 - Папка храннения дефолтных настроек для php-5.6.18
|--------php - Исполняемый файл для php-5.6.18
|--------php.ini - Дефольный файл настроке
|--------php.ini - Дефольный файл настроке
|----/apache-cert - папка хранения сертификатов для apache

Создаем папки для пользователя:

mkdir -p /var/www/users/admin
mkdir -p /var/www/users/admin/domain.ru
mkdir -p /var/www/users/admin/apache-log
mkdir -p /var/www/users/admin/php-bin
mkdir -p /var/www/users/admin/temp
mkdir -p /var/www/users/admin/temp/php-session

Копируем файлы настроек для php:

cp /opt/php/php-5.6.18/fcgi-bin/php /var/www/users/admin/php-bin/php
cp /opt/php/php-5.6.18/fcgi-bin/php.ini /var/www/users/admin/php-bin/php.ini

Создаем юзера (важно помнить что все пользователи в группе admin имеют доступ на запуск программ из sudo, поэтому при выборе имени admin он автоматически будет иметь права на выполнения sudo. В данном примере это не критично, но вам следует помнить об этом при создании пользователя).

useradd -m -s /bin/bash admin
passwd admin

Выставляем владельца папки:

chown admin:admin -R /var/www/users/admin

Выставляем корневую директорию для пользователя:

usermod -d /var/www/users/admin admin

Настраиваем виртуальные хосты в apache:

<VirtualHost *:8080>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/users/admin/domain.ru

	SuexecUserGroup admin admin	

	<IfModule mod_remoteip.c>
	      RemoteIPHeader X-Forwarded-For
	      RemoteIPHeader X-Real-IP
	      RemoteIPInternalProxy 127.0.0.1
	</IfModule>

	<ifmodule mod_rewrite.c>
		RewriteEngine On
		RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
	</ifmodule>


	<IfModule mod_fcgid.c>
	    IPCCommTimeout 7200
	    FcgidConnectTimeout 320
	    MaxRequestLen 25728640
	    FcgidMaxRequestsPerProcess 0
	    FcgidBusyTimeout 3600
	    FcgidOutputBufferSize 0
	</IfModule>

	<FilesMatch "\.ph(p[3-5]?|tml)$">
		SetHandler fcgid-script
		FCGIWrapper /var/www/users/admin/php-bin/php
	</FilesMatch>

	ErrorLog /var/www/users/admin/apache-log/error.log
	CustomLog /var/www/users/admin/apache-log/access.log combined
</VirtualHost>
<Directory /var/www/users/admin/www>
	AllowOverride All
	Options +Includes +ExecCGI
</Directory>

В настройках php.ini пользователя меняем session.save_path
session.save_path = /var/www/users/admin/temp/php-session

Перезапускаем apache:

service apache2 restart

ЭТАП 4 (Установка Nginx с модулем pagespeed от google)

Забегая вперед, для поддержки pagespeed в Nginx требуется пересобрать сам Nginx с этим модулем, но чтобы потом не лазить дополнительно в настройках, проще сначало установить его.
Изменяем порты для Apache:

/etc/apache2/ports.conf
+ Ваши созданные виртуальные хосты

Перезапускаем Apache:

service apache2 restart

Устанавливаем ngnix:

apt-get install nginx

Собираем Nginx с pagespeed

Вначале необходимо установить все необходимы для сборки пакеты:

apt install -y build-essential zlib1g-dev libpcre3 libpcre3-dev unzip libxslt1-dev libgd-dev libgeoip-dev

Создаем папки для исходников nginx:

mkdir -p /opt/source/nginx
cd /opt/source/nginx

Скачиваем и распаковываем pagespeed и psol. Yt cnjbn g

wget https://github.com/pagespeed/ngx_pagespeed/archive/v1.11.33.4-beta.zip
unzip v1.11.33.4-beta.zip
cd ngx_pagespeed-1.11.33.4-beta
wget https://dl.google.com/dl/page-speed/psol/1.11.33.4.tar.gz
tar -xzvf 1.11.33.4.tar.gz

Сам psol скачивается и распаковывается в директории с ngx_pagespeed. Переходим в папку с Ngnix

cd /opt/source/nginx

Проверяем версию ngnix (по умолчанию в ubuntu 16.0.4 устанавливается 1.10.0):

nginx -V

Загружаем т версию NGINX:

wget https://nginx.ru/download/nginx-1.10.0.tar.gz
tar -xvzf nginx-1.10.0.tar.gz

Собираем nginx с теми же параметрами что и установленный, но в конце добавляем дополнительные модули:

cd /opt/source/nginx/nginx-1.10.0
./configure \
--with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads \
--add-module=/opt/source/nginx/ngx_pagespeed-1.11.33.4-beta \
--with-http_mp4_module

Собираем Nginx:

make
make install

Собранный бинарный файл Nginx располагается в директории /opt/source/nginx/nginx-1.10.0/objs/nginx. Для того чтобы установить, требуется просто заменить текущий испоняемый файл Nginx на собранный.

Остановим Nginx, заменим файл, и перезапустим его.

service nginx stop

#Переименовываем (на всякий случай) текущий nginx в nginx_backup:

mv /usr/sbin/nginx /usr/sbin/nginx_backup

# Перемещаем на его место новый собранный бинарник:

mv /opt/source/nginx/nginx-1.10.0/objs/nginx /usr/sbin/nginx

перезапускаем Nginx:

service nginx start

Создаем папку хранения кэша для pagespeed:

/var/www/temp/
/var/www/temp/page-speed/

Добавим /etc/nginx/nginx.conf в секцию http:

pagespeed on;
pagespeed FileCachePath "/var/www/temp/page-speed/";
pagespeed EnableFilters combine_css,combine_javascript,rewrite_images,rewrite_css,rewrite_javascript,inline_images,recompress_jpeg,recompress_png,resize_images;
pagespeed JpegRecompressionQuality 85;
pagespeed ImageRecompressionQuality 85;
pagespeed ImageInlineMaxBytes 2048;
pagespeed LowercaseHtmlNames on;

ЭТАП 5 (Настройка Nginx как reverse proxy )

Скажу скажу что в интернете кучу статей для настройки Nginx как reverse proxy. Я лиш приведу ознакомительный вариант настройки.

server { 

	listen 80; 
	server_name domain.ru; 
	access_log /var/log/nginx.access_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|xml|docx|xlsx)$ { 
		root /var/www/users/admin/domain.ru; 
		index index.html index.php; 
		access_log off; 
		expires 30d; 
		error_page 404 = @prox;
	} 

	location @prox{
		proxy_pass 127.0.0.1:8880; 
		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;
	}


	location ~ /\.ht { 
		deny all; 
	} 


	location / { 
		proxy_pass 127.0.0.1:8880; 
		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; 
	} 
} 


Share post

Comments 22

    +2
    apache php nginx
    уберите лишнее
      +3
      Стоить обратить внимание на строку --prefix=/opt/php/php-5.6.18

      Действительно стоит — почему не 7 версия?
      И зачем там апач?
      Мануал судя по всему скопипащен откуда-то из весьма устаревшего источника, для новичков скорее вреден чем полезен
        0
        Изначально в ubuntu 16.0.4 — уже 7ая версия. Ничто не останавливает собрать 7ую.
        Изначально сервер настраивался для 1C-Bitix, чтобы не было лишних вопрос во поводу совместимоси о обновлений, поэтому apache.
        Дополнительно можно настроить ngnix + php-fcgi. ngnix + node и т.д.
        Мануал не скопипастен, добавил в конец поста ссылки, откуда брал основную инфу
          +2
          Изначально сервер настраивался для 1C-Bitix

          С этого и надо было начинать т.к. весьма специфичный случай
          Ничто не останавливает собрать 7ую.

          Так и сделали бы мануал с оглядкой на это (если конечно чудо-битрикс совместим с php7.*), зачем учить ставить устаревшее ПО?
            0
            Совершенно внезапно чудобитрикс ВМ это: Centos 7 и php 7
              0

              Хм, а когда у меня в конторе ставил полновесный битрикс, то упёрся в то, что php7 официально не поддерживается, а допиливать — не моя область работы, хотя php7 стоял на дворе уже год в виде релиза.
              Хотя вот загуглил — вроде у народа уже работает, хотя и не без ошибок.

                0
                Не, то что бы давно поддерживается, но наверное месяц-два уже выложили новые образы виртуалок нуи всего остального. Проблема то не только в том, что ядро будет работать, но и все модули и прочее тоже смогут жить на 7ке
          0
          > Действительно стоит — почему не 7 версия?
          > 2. Возможность выбора версий PHP

          7 через менеджер пакетов ставится в систему, автор же показывает, что для выбора версии и избежания путаницы — более старую версию ставим в отдельную папку

          я так понимаю, данным способом можно установить любое кол-во версий php и легко переключать их через настройки VirtualHost
            –1
            я так понимаю, данным способом можно установить любое кол-во версий php и легко переключать их через настройки VirtualHost

            а смысл? не проще ли тогда просто использовать шаред-хостинг и не возиться с подобной настройкой?
              0
              > а смысл? не проще ли тогда просто использовать шаред-хостинг и не возиться с подобной настройкой?

              но это была бы уже совсем другая история, не так ли?
                0
                А как вы думаете, как на shared хостинге это настраивается? Именно так, правда вместо того чтобы это делать ручками, это делается черес ispconfig, ispmanager и т.п. Но для полной картины мира, тут показано как все это делается. К тому же shared хостинг, это shared хостинг, кроме как сайта на нем мало что выйдет
                  0
                  Ок, на шаред-хостинге наличие apache+nginx еще оправдано. Ну или в случае с битриксом, но это специфичный случай.
                  Лично мне кажется что если есть доступ к серверу — лучше не извращаться, а сделать с новым ПО и не ставить лишнего, оставив лишь связку nginx+php7.0-fpm — для подавляющего большинства фреймфорков и cms на php этого хватит.
                  Нужно несколько приложений поместить которые работают на старой версии — переписать чтоб были совместимы, либо вынести на отдельный сервер поменьше и не путаться.
                    0
                    Текущая настройка не исключает данного варианта. Если есть желания nginx+php7.0-fpm создаем хост, и пользуемся. Если нет совместимости, настраиваем хост и выбираем версию. Все очень гибко. А вынести на отдельный сервер — это дополнительные материальные затраты на обслуживание. Поправьте если я ошибаюсь
                      0
                      это дополнительные материальные затраты на обслуживание.

                      Да, но это уменьшит время на поддержку — настройки не такие запутанные — настраивать и обслуживать быстрее и проще
                      В итоге получится максимум 2 сервера на которые поместится и будет работать все — один со связкой nginx+php7.0-fpm
                      второй — nginx+apache+php5.6
                      что по стоимости с учетом нынешних тарифов выйдет не так много, а настройка и поддержка каждого будет проще
                        0
                        Если следовать вашей логике, то лучше использовать
                        nginx+php7.0-fpm
                        nginx+php5.6-fpm
                        apache+php5.6
                        apache+php7(mod_apache)
                        И это только в продакшене. Везде есть свои плюсы и минусы. Тут уже тема для холивара, в котором я участвовать не буду.
                        По поводу настройки — не думаю что один раз написать sh скрипт и потом его запускать будет дороже, чем платить за 4 сервера.
                          0
                          скрипт прокатит если у вас все однотипное.
                          А если мне к примеру на один сервер нужно добавить проекты на
                          • Symfony
                          • Laravel
                          • Phalcon
                          • Wordpress
                          • Bitrix

                          то скрипт не поможет т.к. для каждого случая свои настройки
                          И выйдет что разделить на 2 сервера проекты на Laravel,Symfony,Phalcon (nginx+php7.0-fpm), а на другом — Wordpress и битрикс (nginx+apache+php5.6) будет оптимальнее чем настраивать все на одном
                          В прочем да, холиварить незачем, всему свое место и возможно просто субъективно ваше решение мне не подходит, а кто-то ищет именно его
                0
                Все верно, можно прописать в виртуальных хостах, с настройками CGI. и легко их переключать.
              –1
              Спасибо за отличную, актуальную, подробную и познавательную статью!
              • UFO just landed and posted this here
                  0
                  Вместо сборки из исходников, по моему мнению, лучше использовать готовые репозитории. Я использую ppa Ondřej Surý. Банально проще обновлять и ставить.
                  make
                  make install

                  Уже сколько раз писали, что так делать не нужно, есть checkinstall.
                    0
                    есть checkinstall

                    Для простых вещей его хватит, а вот если планируете засунуть пакет в свой репозиторий, то лучше всеже «дебианизировать» и делать dh_make & dpkg-buildpackage, тем более, что тот же nginx архив «дебианизации» выкладывает
                      0
                      Это понятно. В любом случае make install использовать не стоит.

                  Only users with full accounts can post comments. Log in, please.