В посте будут решены и описаны следующий задачи:
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;
}
}
http://www.info-x.org/freebsd/programmy/apache_suexec_php_v_rezhime_cgi.html
http://adminunix.ru/nastrojka-php-5-2-cherez-fastcgi-i-php-5-3-kak-modul-apache2-na/
https://www.server-world.info/en/note?os=Ubuntu_16.04&p=httpd&f=14
http://webew.ru/posts/5351.webew
https://camouf.ru/blog-note/589/
https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=32&CHAPTER_ID=04902&LESSON_PATH=3903.4897.4900.4902
Комментарии (22)
MetaDone
13.06.2017 14:05+3Стоить обратить внимание на строку --prefix=/opt/php/php-5.6.18
Действительно стоит — почему не 7 версия?
И зачем там апач?
Мануал судя по всему скопипащен откуда-то из весьма устаревшего источника, для новичков скорее вреден чем полезенpan-alexey
13.06.2017 14:30Изначально в ubuntu 16.0.4 — уже 7ая версия. Ничто не останавливает собрать 7ую.
Изначально сервер настраивался для 1C-Bitix, чтобы не было лишних вопрос во поводу совместимоси о обновлений, поэтому apache.
Дополнительно можно настроить ngnix + php-fcgi. ngnix + node и т.д.
Мануал не скопипастен, добавил в конец поста ссылки, откуда брал основную инфуMetaDone
13.06.2017 14:34+2Изначально сервер настраивался для 1C-Bitix
С этого и надо было начинать т.к. весьма специфичный случай
Ничто не останавливает собрать 7ую.
Так и сделали бы мануал с оглядкой на это (если конечно чудо-битрикс совместим с php7.*), зачем учить ставить устаревшее ПО?wrewolf
13.06.2017 16:44Совершенно внезапно чудобитрикс ВМ это: Centos 7 и php 7
khanid
13.06.2017 17:21Хм, а когда у меня в конторе ставил полновесный битрикс, то упёрся в то, что php7 официально не поддерживается, а допиливать — не моя область работы, хотя php7 стоял на дворе уже год в виде релиза.
Хотя вот загуглил — вроде у народа уже работает, хотя и не без ошибок.wrewolf
13.06.2017 17:45Не, то что бы давно поддерживается, но наверное месяц-два уже выложили новые образы виртуалок нуи всего остального. Проблема то не только в том, что ядро будет работать, но и все модули и прочее тоже смогут жить на 7ке
Lordbl4
13.06.2017 14:34> Действительно стоит — почему не 7 версия?
> 2. Возможность выбора версий PHP
7 через менеджер пакетов ставится в систему, автор же показывает, что для выбора версии и избежания путаницы — более старую версию ставим в отдельную папку
я так понимаю, данным способом можно установить любое кол-во версий php и легко переключать их через настройки VirtualHostMetaDone
13.06.2017 14:37-1я так понимаю, данным способом можно установить любое кол-во версий php и легко переключать их через настройки VirtualHost
а смысл? не проще ли тогда просто использовать шаред-хостинг и не возиться с подобной настройкой?Lordbl4
13.06.2017 14:43> а смысл? не проще ли тогда просто использовать шаред-хостинг и не возиться с подобной настройкой?
но это была бы уже совсем другая история, не так ли?
pan-alexey
13.06.2017 14:51А как вы думаете, как на shared хостинге это настраивается? Именно так, правда вместо того чтобы это делать ручками, это делается черес ispconfig, ispmanager и т.п. Но для полной картины мира, тут показано как все это делается. К тому же shared хостинг, это shared хостинг, кроме как сайта на нем мало что выйдет
MetaDone
13.06.2017 15:03Ок, на шаред-хостинге наличие apache+nginx еще оправдано. Ну или в случае с битриксом, но это специфичный случай.
Лично мне кажется что если есть доступ к серверу — лучше не извращаться, а сделать с новым ПО и не ставить лишнего, оставив лишь связку nginx+php7.0-fpm — для подавляющего большинства фреймфорков и cms на php этого хватит.
Нужно несколько приложений поместить которые работают на старой версии — переписать чтоб были совместимы, либо вынести на отдельный сервер поменьше и не путаться.pan-alexey
13.06.2017 15:09Текущая настройка не исключает данного варианта. Если есть желания nginx+php7.0-fpm создаем хост, и пользуемся. Если нет совместимости, настраиваем хост и выбираем версию. Все очень гибко. А вынести на отдельный сервер — это дополнительные материальные затраты на обслуживание. Поправьте если я ошибаюсь
MetaDone
13.06.2017 15:19это дополнительные материальные затраты на обслуживание.
Да, но это уменьшит время на поддержку — настройки не такие запутанные — настраивать и обслуживать быстрее и проще
В итоге получится максимум 2 сервера на которые поместится и будет работать все — один со связкой nginx+php7.0-fpm
второй — nginx+apache+php5.6
что по стоимости с учетом нынешних тарифов выйдет не так много, а настройка и поддержка каждого будет прощеpan-alexey
13.06.2017 15:33Если следовать вашей логике, то лучше использовать
nginx+php7.0-fpm
nginx+php5.6-fpm
apache+php5.6
apache+php7(mod_apache)
И это только в продакшене. Везде есть свои плюсы и минусы. Тут уже тема для холивара, в котором я участвовать не буду.
По поводу настройки — не думаю что один раз написать sh скрипт и потом его запускать будет дороже, чем платить за 4 сервера.MetaDone
13.06.2017 15:39скрипт прокатит если у вас все однотипное.
А если мне к примеру на один сервер нужно добавить проекты на
- Symfony
- Laravel
- Phalcon
- Wordpress
- Bitrix
то скрипт не поможет т.к. для каждого случая свои настройки
И выйдет что разделить на 2 сервера проекты на Laravel,Symfony,Phalcon (nginx+php7.0-fpm), а на другом — Wordpress и битрикс (nginx+apache+php5.6) будет оптимальнее чем настраивать все на одном
В прочем да, холиварить незачем, всему свое место и возможно просто субъективно ваше решение мне не подходит, а кто-то ищет именно его
pan-alexey
13.06.2017 14:48Все верно, можно прописать в виртуальных хостах, с настройками CGI. и легко их переключать.
o_serega
13.06.2017 16:12http://uwsgi-docs.readthedocs.io/en/latest/PHP.html Еще один вариант поиметь несколько версий php)
sumanai
13.06.2017 20:22Вместо сборки из исходников, по моему мнению, лучше использовать готовые репозитории. Я использую ppa Ondrej Sury. Банально проще обновлять и ставить.
make
make install
Уже сколько раз писали, что так делать не нужно, есть checkinstall.NickyX3
15.06.2017 18:20есть checkinstall
Для простых вещей его хватит, а вот если планируете засунуть пакет в свой репозиторий, то лучше всеже «дебианизировать» и делать dh_make & dpkg-buildpackage, тем более, что тот же nginx архив «дебианизации» выкладывает
bat
apache php nginx
уберите лишнее