Nginx + PHP-FPM в Debian 7
Введение
В статье рассматривается настройка сервера Debian 7 для размещения проектов PHP в связке с Nginx и PHP-FPM.Долгое время мне вполне хватало возможностей Apache для разработки моих проектов на PHP. Были некоторые трудности с .htaccess и перенаправлением всех запросов на Front Controller, однако, чуть позже я понял, что Apache уже не может полностью удовлетворить моей тяги к максимальной производительности и начал искать другие пути. Почитав, я выяснил, что доля интернет-серверов под управлением Apache неуклонно снижается на протяжении уже нескольких лет, на замену ему приходят другие, которые дают бОльшую произодительность с меньшей затратой машинных ресурсов. Среди множества решений я выбрал PHP-FPM. Судя по тестам производительности, произведённым многими энтузиастами, именно он в связке с Nginx является наиболее перспективным способом размещения сайтов на PHP.
Цели
- Увязка PHP-FPM с nginx
- Конфигурирование параметров сайта для его корректной работы через Front Controller
Установка необходимого ПО
Добавим в список репозитории nginx, предварительно создав файл nginx.list
в каталоге /etc/apt/sources.list.d/
:
cd /etc/apt/sources.list.d/
touch nginx.list
/etc/apt/sources.list.d/nginx.list
deb http://nginx.org/packages/debian/ wheezy nginx
deb-src http://nginx.org/packages/debian/ wheezy nginx
Скачиваем ключ репозитория:
wget http://nginx.org/keys/nginx_signing.key
Установка ключей в deb-системах делается так:
apt-key add nginx_signing.key
Теперь можно выполнить установку всех необходимых программ:
apt-get update && apt-get install php5 php5-fpm nginx -y
Кратко по списку:
- php5 и php5-fpm - интерпретатор и FastCGI-сервер для него
- nginx - проксирующий сервер, будет нашим Front-End, т.е. сервером, принимающим запросы пользователя. Не путать с Front Controller, это совершенно разные вещи!
Настройка PHP и PHP-FPM
При установке PHP-FPM создаёт внутри каталога /etc/php5 подкаталог fpm. Внутри этого каталога находится несколько нужных нам файлов и подкаталогов. Первым делом вносим изменения в файл /etc/php5/fpm/php.ini
cd /etc/php5/fpm
nano php.ini
Здесь множество настроек, которые влияют на поведение PHP. В качестве символа комментария следует использовать точку с запятой. Самыми полезными я считаю следующие настройки:
- short_open_tag = Off - использование коротких тегов считать ошибкой. Официальная документация по PHP рекомендует не использовать короткие теги.
- asp_tags = Off - мы тут всё-таки на PHP пишем, а не на ASP.NET
- max_execution_time = 60 - для некоторых CMS, например, Drupal, стандартных 30 секунд часто не хватает для выполнения некоторых скриптов, например, обновления
- error_reporting = E_ALL - разработчику нужно видеть все ошибки. Если сервер боевой, нужно выставить в значение E_ALL & ~E_DEPRECATED & ~E_STRICT
- display_errors = On - для разработки, для боевых условий - Off
- display_startup_errors = On - аналогично
- post_max_size = 16M - можно и больше, если через POST будут передаваться достаточно большие объёмы данных
- default_charset = "UTF-8" - обязательно, если хочется избавиться от большинства проблем с кодировкой. Осторожно! Настройка влияет на весь сервер. Также кодировку можно задать в самом скрипте!
- cgi.fix_pathinfo=1 - пригодится, если приложение работает через Front Controller
- upload_max_filesize = 32M - можно и больше, если на сервер будут загружаться большие файлы
- default_socket_timeout = 60 - в нашем случае связь с Nginx будет именно через сокет. Не стоит выставлять слишком большие значения, это приведёт к падению производительности.
Остальные настройки в этом файле можете делать по своему усмотрению.
Теперь нужно подредактировать файл www.conf
в каталоге pool.d/www.conf
nano pool.d/www.conf
Следует изменить user и group на те, от имени которых будут выполняться скрипты. Не следует выполнять их от имени root, это дыра в безопасности. Я рекомендую указывать здесь владельца каталога /var/www
user = www-data
group = www-data
Не менее важная настройка:
listen = /var/run/php5-fpm.sock
Именно через этот сокет будет производиться обмен данными с Nginx. Остальные настройки я рекомендую оставить по умолчанию. Их тонкая настройка заслуживает отдельной подробной статьи.
После сохранения изменений следует перезапустить php-fpm:
service php5-fpm restart
Настройка Nginx
Перейдём в каталог настроек nginx:
cd /etc/nginx/
Здесь нам нужны 2 файла:
- nginx.conf - основной файл конфигурации сервера
- fastcgi_params - настройки Nginx для работы с FastCGI-серверами, например, PHP-FPM
Я привёл содержимое этих файлов к следующему виду:
nginx.confuser nginx;
worker_processes 2; # По числу ядер/процессоров, либо эмпирическим путём
worker_priority -5; # Отрицательные числа задают более высокий приоритет
worker_rlimit_nofile 2048; # Можно открыть сразу 2048 подключений без изменения параметров ядра
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 60; #Поддерживать подключение 1 минуту
client_max_body_size 20m; #Разрешить загрузку файлов до 20 МБ
server_tokens off;
#Сжатие передаваемых данных
gzip on;
gzip_disable "msie6";
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml+rss text/javascript;
include /etc/nginx/conf.d/*.conf;
}
В конец файла fastcgi_params нужно добавить всего одну строчку, вот эту:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
Теперь в каталоге /etc/nginx/conf.d/ создадим файл site.conf
nano /etc/nginx/conf.d/site.conf
index index.php;
server {
server_name www.site.ru;
rewrite ^ $scheme://site.ru$request_uri? permanent;
}
server {
server_name site.ru;
access_log /var/www/site.ru/log/access.log;
error_log /var/www/site.ru/log/error.log;
root /var/www/site.ru;
location / {
try_files $uri $uri/ /index.php?$request_uri;
index index.php;
}
location ^~ /protected/ {
deny all;
}
location ~ \.php$ {
try_files $uri = 404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
Разберём по частям этот файл:
index index.php;
Считать страницей по-умолчанию index.php
server {
server_name www.site.ru;
rewrite ^ $scheme://site.ru$request_uri? permanent;
}
Все запросы на http://www.site.ru автоматически переадресовывать к http://site.ru/
server_name site.ru;
access_log /var/www/site.ru/log/access.log;
error_log /var/www/site.ru/log/error.log;
root /var/www/site.ru;
Собственно наш сервер, с указанием его имени, логов и указанием корневого каталога
location / {
try_files $uri $uri/ /index.php?$request_uri;
index index.php;
}
Тут указано, что все запросы вида http://site.ru/login/auth следует переадресовывать к http://site.ru/index.php - как раз то, что нужно для Front Controller'а
location ^~ /protected/ {
deny all;
}
Запрещаем любые обращения к папке protected
нашего сайта. Там лежат исходные коды, к которым будет обращаться только index.php
, веб-сервер их отдавать не должен.
location ~ \.php$ {
try_files $uri = 404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
Выдавать ошибку 404, если запрошенный php-файл не найден. В остальном - просто переадресовать запрос на наш PHP-FPM-сервер. Также в этих строках выполняется подключение файла настроек /etc/nginx/fastcgi_params
.
После выполнения всех операций следует перезапустить сервис Nginx
service nginx restart
Если исходные файлы сайта размещены в каталоге /var/www/site.ru/
, а также этот каталог содержит подкаталог log, владельцем которого является www-data, то при обращении к сайту мы увидим главную страницу.
Оптимизация PostgreSQL
В этой статье я хочу поделиться своими знаниями в области оптимизации PostgreSQL и ссылками на весьма авторитетные источники. Очень подробное руководство с полным описанием всех параметров настройки производительности (и не только) СУБД PostreSQL написал Алексей Васильев.
Вот его страничка.
А вот его замечательная книга.
Книга распространяется абсолютно бесплатно, кроме того, описанные в ней приёмы актуальны для последних версий PostgeSQL. От себя хочу лишь добавить небольшую выдержку из этого фундаментального труда.
Для оптимизации PostgreSQL я использую утилиту pgtune.
apt-get install pgtune
После её установки надо скопировать конфигурационный файл postresql.conf и запустить эту утилиту с некоторыми параметрами:
cd /etc/postgresql/9.3/main cp postgresql.conf postgresql.conf.bak pgtune -i postgresql.conf.bak -o postgresql.conf
Кратко по параметрам:
-i postgresql.conf.bak
Задаёт имя файла, настройки из которого нужно взять за основу
-o postgresql.conf
Имя файла, в который нужно вывести оптимизированные настройки.
Помимо этих двух параметров утилита pgtune имеет ещё кучу дополнительных опций. Самой полезной лично для меня оказалась директива
--typeОна позволяет указать, для каких целей планируется использовать СУБД, что влияет на параметры оптимизации. Для веб-сайтов, например, можно написать вот так:
pgtune -i postgresql.conf.bak -o postgresql.conf --type web
Другие ключи можно посмотреть в описании утилиты по команде
man pgtune
Сборка PIL с зависимостями (Debian 7)
Описание проблемы
Несмотря на то, что уже давно существует и активно развивается библиотека Pillow, импортирующая функции для обработки изображений средствами Python, в некоторых проектах до сих пор используется устаревший (последняя версия вышла в 2009 году) модуль PIL. Если Вы из тех "везунчиков", кому приходится поддерживать старые проекты, то эта статья для Вас. При установке PIL в виртуальное окружение вводится командаpip install pilПосле этого начинается процесс загрузки расширения и его сборки, выводится куча сообщений, и в самом конце можно увидеть следующий текст:
PIL 1.1.7 SETUP SUMMARY -------------------------------------------------------------------- version 1.1.7 platform linux2 2.6.8 (unknown, Jan 26 2013, 14:35:25) [GCC 4.7.2] -------------------------------------------------------------------- *** TKINTER support not available (Tcl/Tk 8.5 libraries needed) *** JPEG support not available *** ZLIB (PNG/ZIP) support not available *** FREETYPE2 support not available *** LITTLECMS support not available -------------------------------------------------------------------- To add a missing option, make sure you have the required library, and set the corresponding ROOT variable in the setup.py script.Что означает примерно следующее: модуль успешно собран, но работать не будет, т.к. ни одно из требующихся расширений установлено не было. Немного погуглив, я натолкнулся на кучу форумов, где описывалось решение, заключающееся в создании символических ссылок на нужные библиотеки в каталоге /usr/lib, однако, ни одно из этих решений не оказалось рабочим. В этой статье я описываю своё решение сборки PIL с поддержкой практически всех нужных расширений.
Установка
Для сборки и установки PIL с зависимостями нам потребуются некоторые дополнительные пакеты- python2.6-dev - заголовочные файлы для сборки Python2.6. Если используете другой - указываете другой.
- libjpeg62-dev - для поддержки JPEG (в Debian есть также libjpeg8-dev, но она не подойдёт)
- zlib1g-dev - поддержка PNG
- libfreetype6-dev - поддержка шрифтов
- liblcms1-dev - поддержка LITTLE CMS. Что это такое, я не знаю, можно не ставить.
apt-get install libjpeg62-dev zlib1g-dev libfreetype6-dev liblcms1-devВсе необходимые зависимости, в том числе GCC, если он не установлен, установятся сами. Итак, необходимые системные пакеты установлены. Теперь нужно будет сделать несколько дополнительных действий с самой библиотекой. Первым делом её нужно скачать с официального сайта.
wget http://effbot.org/downloads/Imaging-1.1.7.tar.gzРаспакуем архив:
tar xfv Imaging-1.1.7.tar.gzЗайдём в созданную папку и отредактируем файл setup.py
cd Imaging-1.1.7 nano setup.pyТут нужно внести следующие изменения:
TCL_ROOT = NONE JPEG_ROOT = NONE ZLIB_ROOT = NONE TIFF_ROOT = NONE FREETYPE_ROOT = NONE LCMS_ROOT = NONEзаменяем на
TCL_ROOT = '/usr/lib/x86_64-linux-gnu/' JPEG_ROOT = '/usr/lib/x86_64-linux-gnu/' ZLIB_ROOT = '/usr/lib/x86_64-linux-gnu/' TIFF_ROOT = '/usr/lib/x86_64-linux-gnu/' FREETYPE_ROOT = '/usr/lib/x86_64-linux-gnu/' LCMS_ROOT = '/usr/lib/x86_64-linux-gnu/'В x86-системах вместо x86_64 нужно вводить i386. Тем самым мы указываем, откуда брать библиотеки. Теперь можно попробовать собрать PIL со всеми расширениями (без реальной установки):
python setup.py build_ext -iЕсли сообщение выглядит примерно так:
-------------------------------------------------------------------- PIL 1.1.7 SETUP SUMMARY -------------------------------------------------------------------- version 1.1.7 platform linux2 2.6.8 (unknown, Jan 26 2013, 14:35:25) [GCC 4.7.2] -------------------------------------------------------------------- *** TKINTER support not available (Tcl/Tk 8.5 libraries needed) --- JPEG support available --- ZLIB (PNG/ZIP) support available --- FREETYPE2 support available --- LITTLECMS support available -------------------------------------------------------------------- To add a missing option, make sure you have the required library, and set the corresponding ROOT variable in the setup.py script.можно смело устанавливать PIL в виртуальное окружение Вашего проекта. Перед этим рекомендую удалить старую версию через
pip uninstall pil -yи удалить файлы в каталоге lib/site-packages виртуального окружения:
cdsitepackages rm -rf PIL*Установка PIL:
python setup.py install
Заключение
В некоторых проектах БАРС Груп используется PIL, он прописан в зависимостях для установки их пакетов через setup-tools. В этом случае я делаю так:- Устанавливаю PIL
- Устанавливаю пакет, провожу миграции и т.д.
- Удаляю PIL и ставлю Pillow, т.к. Pillow импортирует те же самые функции и пространства имён, что и PIL.
Gunicorn + NGinx + Virtualenv на Debian 7
В этой заметке я хочу рассмотреть наиболее перспективный в настоящее время способ размещения проектов на базе Django на боевых серверах. Будет использовано следующее ПО:
- Python 2.6. Вы можете использовать вообще любой, какой Вам нравится, просто проекты, которыми пользуется моя организация, используют именно его. По умолчанию в Debian 7 установлен Python 2.7, но без проблем можно установить и более старую версию. Проблем с 3-ей версией также не возникнет, он есть в стандартных репозиториях.
- Virtualenv и virtualenvwrapper. Благодаря этим пакетам можно создать свою песочницу для каждого проекта Django, указав свой собственный интерпретатор Python (2.6, 2.7, 3, 3.1 - и всё на одной машине) и набор пакетов (а также версий пакетов). Данное ПО позволяет изолировать проекты друг от друга, при необходимости используя разные версии библиотек. Допустим, в одном проекте используется lxml версии 2.3.1, а в другом 3.2.1. Как быть? Просто добавляем в одно окружение 2.3.1, а в другое - 3.2.1, и никаких конфликтов библиотек не будет.
- Gunicorn. Этот легковесный сервер позволяет размещать на одном сервере проекты, использующие разные версии Python. В отличие от
apache2-mod-wsgi
, он позволяет работать одновременно и с Python2.6, и с Python2.7 (имеется ввиду разделение по проектам). Работа же mod-wsgi глобальна, т.е. весь сервер сразу поддерживает либо одну версию Python, либо другую. - Supervisor. Эта утилита позволяет демонизировать процессы. В рассматриваемом случае она будет запускать gunicorn-серверы проектов. Некоторые скажут, что можно использовать
init
. Пожалуйста, я никого не заставляю, но настроек для init'а у меня нет. - PostgreSQL. Наиболее продвинутая из бесплатных и максимально соблюдающая SQL-стандарты из известных мне СУБД. С помощью утилиты
pgtune
можно в автоматическом режиме оптимизировать настройки (содержимое файлаpostgresql.conf
) под конкретную машину с учётом размера оперативной памяти, дискового кэша и т.д. - Nginx. В представлении не нуждается. Самый производительный web-сервер в мире на сегодня.
- Пакеты для работы с графикой, XML и сборки драйвера
psycopg2
PostgreSQL для Python (ставить желательно, но не обязательно):libfreetype6-dev
- позволяет Pillow выводить надписи на изображенияzlib1g-dev
- включает поддержку PNG-формата для Pillowlibjpeg8-dev
- позволяет Pillow обрабатывать JPEG-изображенияlibwebp-dev
- позволяет Pillow работать с форматом webplibtiff-dev
- комментарии излишниliblcms2-dev
- для поддержки библиотеки управления цветовыми профилями Little Color Management System версии 2.libpq-dev
- без этого пакета в виртуальном окружении не соберётся пакетpsycopg2
, необходимый для использования PostgreSQLlibxml2-dev, libxslt1-dev
- без этих двух пакетов в виртуальном окружении не соберётся пакетlxml
Установка пакетов
Для работы нам понадобится установить некоторые пакеты в систему, но прежде чем приступить к установке, нужно будет добавить репозитории PostgreSQL и Nginx в систему, чтобы всегда использовать последние стабильные версии ПО. Переходим в каталог, содержащий файлы с указанием дополнительных репозиториев apt:
cd /etc/apt/sources.list.d/
Создадим здесь два файла со следующим содержимым:
Первый - postgresql.list
deb http://apt.postgresql.org/pub/repos/apt/ wheezy-pgdg main
Второй - nginx.list
deb http://nginx.org/packages/debian/ wheezy nginx
deb-src http://nginx.org/packages/debian/ wheezy nginx
Конечно, можно добавить эти строки в файл /etc/apt/sources.list
, но я предпочитаю не трогать его, а добавлять сторонние репозитории через создание отдельных .list-файлов в каталоге /etc/apt/sources.list.d/
.
На следующем этапе следует добавить ключи для проверки пакетов. Здесь для nginx, здесь для PostgeSQL.
Собственно команды:
wget http://nginx.org/keys/nginx_signing.key
wget https://www.postgresql.org/media/keys/ACCC4CF8.asc --no-check-certificate
apt-key add nginx_signing.key
apt-key add ACCC4CF8.asc
Кратко опишу смысл указанных выше команд.
С помощью утилиты wget
были скачаны 2 файла. При этом во втором случае была отключена проверка сертификата для шифрованного соединения по протоколу SSL. Сделано это потому, что у сайта PostgreSQL на момент написания статьи были какие-то проблемы с сертификатом и wget не начинал загрузку, выдавая вместо этого сообщение об ошибке.
Далее с помощью команды apt-key add
идёт импорт скачанных ключей в системное хранилище. Debian не работает с репозиториями, для которых у него нет ключей проверки цифровой подписи.
Теперь нужно обновить список доступных пакетов с помощью команды apt-get update
и установить необходимое ПО с помощью apt-get install
:
apt-get update
apt-get install libfreetype6-dev zlib1g-dev libjpeg8-dev libwebp-dev postgresql-9.3 postgresql-server-dev-9.3 postgresql-contrib-9.3 pgtune libpq-dev libxml2-dev nginx python-pip python-setuptools python-virtualenv virtualenvwrapper python-elementtidy supervisor python2.6-dev
Пакет gunicorn
следует ставить отдельно, прямо в виртуальное окружение, поэтому здесь его указывать не надо.
Настройка виртуальных окружений и среды
Запуск любых серверных скриптов должен происходить под ограниченной учётной записью. В Debian по умолчанию для этого используется учётная запись www-data
. Откройте файл /etc/passwd
и убедитесь также, что данному пользователю запрещён вход в систему. При необходимости приведите вот эту строку
www-data:x:33:33:www-data:/var/www:/bin/bash
к вот такому виду:
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
Перейдите в каталог /var
и посмотрите, имеется ли там папка www
. Если её нет, надо её создать и сделать владельцем пользователя www-data
:
cd /var
mkdir www
chown www-data:www-data www/
Теперь нужно будет войти в систему от имени этого пользователя. Так как мы запретили ему вход с использованием шелла, придётся использовать sudo
с параметром -s
, задающим командную оболочку:
sudo su www-data -s /bin/bash
Без параметра -s
система выдаст сообщение, что указанная учётная запись недоступна.
При первом входе в систему в домашнем каталоге пользователя будет создана папка .virtualenvs
, о чём будут выведены сообщения.
Создадим виртуальное окружение:
mkvirtualenv project --python=/usr/bin/python2.6
Созданное окружение project
будет содержать в себе Python 2.6, не будет видеть пакеты, установленные на уровне всей системы, и может быть активировано командой workon
, а деактивировано командой deactivate
:
workon project
deactivate
Если вызвать команду workon
без параметров, она вернёт список имеющихся виртуальных окружений. Помните, что у каждого пользователя свой набор этих окружений, поэтому результат работы этой команды у каждого пользователя будет свой.
Настройка PostgreSQL
Перейдём в каталог с настройками PostgreSQL:
cd /etc/postgresql/установленная_версия/main/
Настроим доступ к базам по паролю, без наличия учетной записи в системе, для этого изменим в файле pg_hba.conf
строку
local all all ident
на
local all all md5
Создадим резервную копию файла настроек, оптимизируем настройки с помощью pgtune
и перезапустим службу:
cp postgresql.conf postgresql.conf.bak
pgtune -i postgresql.conf.bak -o postgresql.conf --type=web
service postgresql restart
В версиях PostgreSQL до 9.2 включительно оптимизация настроек с помощью pgtune
требует также изменения параметров ядра. Прежде всего надо будет выполнить вот этот скрипт:
#!/bin/bash
# simple shmsetup script
page_size=`getconf PAGE_SIZE`
phys_pages=`getconf _PHYS_PAGES`
shmall=`expr $phys_pages / 2`
shmmax=`expr $shmall \* $page_size`
echo kernel.shmmax = $shmmax
echo kernel.shmall = $shmall
Строки, которые выведет этот скрипт, следует добавить в начало файла /etc/sysctl.conf
и перезагрузить систему.
Для создания БД проекта следует запустить интерпретатор PostgreSQL от имени пользователя postgres
:
su -c psql postgres
При выполнении SQL-запросов точка с запятой в конце обязательна. Команды, начинающиеся со знака \, вводятся как есть.
Создадим роль project
с паролем project
и возможностью подключаться к СУБД:
CREATE ROLE project WITH PASSWORD 'project' LOGIN;
Добавим БД project_db
, с которой будет работать эта роль:
CREATE DATABASE project_db WITH OWNER project;
Проверим список имеющихся баз данных с помощью команды \l
и завершим работу с интерпретатором \q
.
Установка пакетов виртуального окружения
Снова залогинимся от имени пользователя www-data
. Активируем виртуальное окружение и запустим в нем команду на установку пакетов:
sudo su www-data -s /bin/bash
workon prject
pip install lxml psycopg2 gunicorn Pillow
Если некоторые пакеты должны ставиться из каких-либо внешних репозиториев, следует передать дополнительные параметры:
pip install myPackage -i http://mysite.ru/simple/
Здесь после ключа i
идёт указание стороннего репозитория.
Настройка Gunicorn
Для соединения Gunicorn'а с Nginx'ом будем использовать сокеты. В каталоге /var/www/
создадим каталог sockets
cd /var/www
mkdir sockets
chown www-data:www-data sockets/
Теперь в каталоге с настройками проекта /var/www/project/conf
создадим файл gunicorn.conf.py
со следующим содержимым:
#! coding: utf-8
import os
import multiprocessing
os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings'
short_name = 'project' # Это имя будет далее использоваться для создания сокета
bind = "unix:/var/www/sockets/%s.sock" % (short_name)#Создаём сокет
proc_name = short_name
workers = multiprocessing.cpu_count() * 2 + 1 #Кол-во воркеров вычисляется по рекомендуемой формуле
print "Socket started"
user = "www-data"
group = "www-data"
errorlog = "/var/www/project/log/gunicorn.log"
loglevel = "warn"
timeout = 30 # 30 секунд на завершение воркера при получении сигнала к завершению
keepalive = 5 #Поддерживать каждое подключение 5 секунд
Указанное содержимое затем будете передано gunicorn'у в качестве параметров. Подробно про переменные, использованные в этом файле, можно почитать здесь. Следует сделать этот файл исполнимым:
chmod u+x gunicorn.conf.py
Настройка supervisor
Установим:
apt-get install supervisor -y
Перейдём в каталог /etc/supervisor/conf.d
и создадим файл настроек для нашего проекта (вместо vim новичкам советую использовать nano):
cd /etc/supervisor/conf.d
touch project.conf
vim project.conf
Содержимое файла project.conf
[program:project]
environment=DJANGO_SETTINGS_MODULE="project.settings",PYTHONIOENCODING="UTF-8",LANG="ru_RU.UTF-8",LC_ALL="ru_RU.UTF-8",LC_LANG="ru_RU.UTF-8"
command=/var/www/.virtualenvs/project_env/bin/gunicorn_django -c /var/www/project/conf/gunicorn.conf.py
directory = /var/www/project
user="www-data" #По аналогии с gunciron.conf.py
group="www-data"
stderr_logfile = /var/www/project/log/supervisor_error.log
Пожалуй, самой интересной является здесь строка, описывающая переменные окружения. В частности, она указывает, какие локали использовать. Без указания правильных локалей при загрузке или обработке приложением файлов, содержащих в имени символы, коды которых выходят за границы основной таблицы ASCII, можно будет полюбоваться ошибкой Non-Unicode character at position ...
В принципе, последняя строка необязательна, но лог ошибок позволит быстро разобраться в возникающих проблемах приложения. После сохранения файла следует выполнить обновление данных supervisor'а и посмотрим статус нашего проекта:
supervisorctl update
supervisorctl status project
Если всё хорошо, на экран будет выведено примерно следующее:
project RUNNING pid 2801, uptime 0:02:05
Больше делать ничего не надо, supervisor будет сам стартовать после перезагрузки системы и автоматически запускать все демоны. Для сервисного обслуживания БД или обновления сайта следует остановить демон командой stop
, запустить заново командой start
:
supervisorctl stop project
...
Какие-то сервисные работы, например, обновление Django, проведение миграций и т.д.
...
supervisorctl start project
Настройка nginx
Возможно, в Вашем случае на одной машине будет несколько сайтов, поэтому дабы не повторяться, некоторые настройки следует вынести в отдельный файл. В каталоге /etc/nginx
создадим файл proxy_params.conf
/etc/nginx/proxy_params.conf
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 20m;
client_body_buffer_size 1m;
proxy_buffering off;
proxy_connect_timeout 360;
proxy_send_timeout 260;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 1m;
Данная конфигурация успешно работает на машине с 4 Гб RAM и далеко не топовой конфигурацией. Также следует немного модифицировать /etc/nginx/nginx.conf
(Вы ведь не забыли сначала сделать его резервную копию, правда?).
user nginx;
worker_processes 2;
worker_priority -5;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
timer_resolution 100ms;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 2;
client_max_body_size 10m;
gzip on;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml+rss text/javascript;
include /etc/nginx/conf.d/*.conf;
}
Единственное, на что здесь следует обратить внимание - это параметры client_max_body_size
и gzip
. По умолчанию максимальный размер одного пакета, который пропускает nginx, равен 24 КБ. В случае, если пользователь захочет загрузить на сайт фотографию размером 30 КБ (смешно, правда, особенно после 41 МП на некоторых смартфонах?), он получит ошибку 304, поэтому данное значение следует в разумных пределах увеличить. gzip позволяет снизить расход трафика, используя сжатие для указанных типов содержимого (список gzip_types). В остальном данный файл практически не отличается от оригинального.
В каталоге /etc/nginx/conf.d/
создадим файл project.conf
/etc/nginx/conf.d/project.conf
upstream project {
server unix:/var/www/sockets/project.sock fail_timeout=0;
}
server {
listen 80;
server_name project.ru www.project.ru;
access_log off;
error_log /var/www/project/log/nginx_error.log crit;
location / {
proxy_pass http://project;
include /etc/nginx/proxy_params.conf;
}
location /static/ {
root /var/www/project/static;
expires 3d;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt|xlsx|doc|docx|pdf|rar|zip|7z|exe)$ {
root /var/www/project/;
expires 3d;
add_header Cache-Control: public;
access_log off;
error_log /var/www/project/log/nginx_static_error.log;
}
}
Данный конфиг указывает, что динамические запросы следует передавать на сервер, подключенный к сокету /var/www/sockets/project.sock
. Для раздачи статики, т.е. запросов, в которых встречается строка /static/
, следует использовать содержимое каталога /var/www/project/static/
. После сохранения настроек следует перезапустить nginx:
service nginx restart
Если всё сделано правильно, после ввода адреса в браузере мы попадём на сайт.
Apache2, nginx, virtualenv и Python 2.6 в Debian
Как я уже писал, в моей компании многие продукты писаны на Python, при том некоторые на Python 2.6, что не может не удручать, т.к. в большинстве популярных дистрибутивов давно используется Python 2.7 и выше. В этой статье рассказывается, как настроить Debian 7.1 Wheezy. Как обычно, всё делается под root или через sudo. Явно я об этом больше нигде в статье писать не буду.
Собственно, почему Debian?
В отличие от той же CentOS 6.4 Debian удобнее в администрирование. Говоря это, я имею ввиду, не количество пакетов, а то, что он "из коробки" имеет кучу оптимальных настроек, в то время как в CentOS приходится всё допиливать под себя.
- Огромное количество пакетов. Я не знаю, есть ли где-то ещё больше. Если есть - напишите мне.
- Python 2.6 в официальном репозитории. Да, Debian 7.1 не требует возни с дохлыми змеями.
- Под него есть официальные сборки PostgreSQL и Nginx. Я раньше тоже думал, что MySQL наше всё, а сейчас вообще не понимаю, как можно пользоваться этой поделкой, не соблюдающей 90% мировых SQL-стандартов. Да, если вы пишете скрипты, руководствуясь SQL-92 или SQL-99, можете быть уверены, что в PostgreSQL они будут работать без каких-либо изменений, в то время как в MySQL их придётся переписывать, и весьма основательно (к слову, в разработке PostgreSQL принимают участие несколько профессоров математики и информатики, что как бы говорит о качестве получающегося продукта).
- Стабильность. Пакеты старые, но если они есть в репозитории, то можно не сомневаться, что они будут работать так, как то ожидается.
Немного про виртуальные окружения
Пакет python-virtualenv
позволяет на одной системе иметь несколько версий не только интерпретатора, но и одних и тех же пакетов. Допустим, нужно, чтобы проект работал с soaplib версии 0.8.0, а при очередном плановом обновлении системы версия пакета повысится до 1.0.0, некоторые функции будут удалены как устаревшие, в итоге приложение перестанет работать вовсе. Чтобы такого не случалось, лучше всего вовремя создать виртуальное окружение. Пакеты в нём будут именно той версии, которая нужна, независимо от того, какая версия пакета установлена в системе.
Также следует пару слов сказать про пакет virtualenvwrapper
. Это небольшой скрипт для ленивых питонистов, который позволяет удобно и быстро управлять созданными виртуальными окружениями.
Бывает два вида виртуальных окружений - изолированные и открытые. Отличия таковы: изолированное окружение не видит пакетов, установленных в системе. При создании открытого виртуального окружения можно быть уверенным, что приложение будет видеть те пакеты, что установлены в системе. Если, например, все приложения используют psycopg2
, lxml
и pytz
одной и той же версии, почему бы не установить его на уровне системы, а затем не заставить окружения "видеть" его?
Nginx как фронтэнд Apache2
В этой статье не будет рассказываться, как заставить Nginx работать в связке с Gunicorn и Supervisor. Я расскажу, как научить Nginx раздавать статику, а все остальные запросы переадресовывать Apache. Сразу скажу о недостатках используемого подхода.
- Первое - модуль
mod_wsgi
, необходимый для увязки Apache с Python. Ограничение тут такое, что этот модуль может работать только с одной версией Python, т.е. заставить его обрабатывать проекты, работающие на Python2.6 и также проекты на Python2.7 не получится, нужно выбрать что-то одно. При неправильном выборе версии будете получать ошибкуNo module named django.core.handlers.wsgi
. Об этом чуть позже. - Второе - прожорливость Apache. Nginx частично решит проблему, тем не менее, без тонкой настройки Apache ест ОЧЕНЬ много памяти и создаёт отдельный процесс на КАЖДОЕ подключение, что не есть хорошо.
Установка пакетов
Первым делом нужно добавить репозиторий nginx и ключ для него в список пакетов apt. Многие рекомендуют отредактировать файл /etc/apt/sources.list. Мне это решение не по душе, т.к. я считаю, что там должны быть только те репозитории, которые относятся непосредственно к системе, поэтому делаем так:
nano /etc/apt/sources.list.d/nginx.list
В этот файл нужно написать:
deb http://nginx.org/packages/debian/ wheezy nginx
deb-src http://nginx.org/packages/debian/ wheezy nginx
Соответственно, если используется другая версия, нужно написать её имя. Для Ubuntu нужно также заменить /debian/ на /ubuntu/.
Нужно скачать публичный ключ репозитория и установить его в систему, делается так:
wget http://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key
Если wget откажется скачивать ключ (во всяком случае, такое было у меня при добавлении репозитория PostgreSQL), необходимо также добавить параметр --no-check-certificate
.
Делаем обновление списка доступных для установки пакетов, обновление устаревших и установку nginx
apt-get update && apt-get dist-upgrade && apt-get install nginx -y
Когда поставится, можно будет увидеть сообщение об успешной установке.
Теперь установка остальных пакетов и Apache2:
apt-get install apache2 libapache2-mod-wsgi libapache2-mod-rpaf python-dev libxml2-dev libxslt1-dev libpq-dev python-pip python-setuptools python-virtualenv virtualenvwrapper -y
По шагам:
apache2
- сам сервер, обязательноlibapache2-mod-wsgi
- обязательно, без него не получится увязать Apache с Python'омlibapache2-mod-rpaf
- обязательно, иначе при работе в связке с nginx Apache не будет отличать одно подключение от другогоpython2.6-dev
- обязательно, нужен, если расширения для Python будут собираться в виртуальном окружении (а они будут!)libxml2-dev
,libxslt1-dev
- нужны для сборки и корректной работы библиотек lxml, xmlsec и других в виртуальном окружении, ставить по желанию (если не поставить, собрать, например, пакет lxml в виртуальном окружении не получится)libpq-dev
- опционально, если используется модуль psycopg2python-pip
- опционально, для установки пакетов Python, распространяемых в исходных кодах. Рекомендую в систему ставить пакет из репозиториев Debian, а в виртуальные окружения через easy_install pippython-setuptools
- обязательно, для установки пакетов в формате egg (вообще setuptools может ставить и другие форматы пакетов, но он всё равно нужен для последующей установки pip)python-virtualenv
,virtualenvwrapper
- рекомендуется, первый для создания виртуальных окружений, второй для удобного управления ими
Помимо этих пакетов apt сам подтянет кучу зависимостей, нужно их все поставить.
Если Вы не стали ставить системный pip, его можно поставить следующей командой:
easy_install pip
По команде pip freeze
можно увидеть список установленных пакетов и их версий, либо сообщение об ошибке. Ничего страшного, работе это не помешает.
Если установка прошла успешно, можно приступать ко второму этапу.
Настройка виртуальных окружений
Перед тем, как приступать к настройке виртуальных окружений, желательно добавить в начало своего .bashrc
следующее:
export WORKON_HOME=/var/www/.virtualenvs
export VIRTUALENVWRAPPER_LOG_DIR=/var/www/.virtualenvs
export VIRTUALENVWRAPPER_HOOK_DIR=/var/www/.virtualenvs
Естественно, папка /var/www/.virtualenvs
должна существовать и быть доступной для записи для текущего пользователя. Если определения этих переменных не будет, virtualenv создаст папку .virtualenvs
в домашнем каталоге пользователя. Итак, переопределили папку для хранения виртуальных окружений и где их должен искать workon (команда будет доступна после установки virtualenvwrapper, без параметров выдаёт список существующих окружений). Нужно перелогиниться либо перечитать файл настроек .bashrc
:
source .bashrc
Примечание: не надо редактировать /etc/bash.bashrc
, начнутся конфликты из-за того, что после root никто не сможет писать в указанную папку виртуальных окружений, эти настройки делаются в файле пользователя, который будет с этими окружениями работать.
Создадим виртуальное окружение командой (под обычным пользователем):
mkvirtualenv new_env --python=/usr/bin/python2.6
Этой командой мы создали в каталоге /var/www/.virtualenvs
каталог new_env
, куда поместили одноимённое окружение, которое будет работать с Python2.6. Если не указывать ключ --python
, окружение будет работать с тем интерпретатором, на который указывает мягкая ссылка в каталоге /usr/bin
(в Debian 7 по умолчанию это Python2.7). Некоторые пишут, что обязательно нужно также указать --no-system-site-packages
. У меня встречный вопрос: зачем, если по умолчанию все окружения и так создаются с этим ключом? Переопределить ссылку на интерпретатор Python можно так (под root):
cd /usr/bin
rm -f python
ln -s python2.6 python
Теперь команда workon
выдаст нам список наших окружений, а команда workon %имя_окружения%
его активирует.
workon new_env
Слева от интерпретатора появится подсказка, например, такая:
(new_env)xphoenix@debian:/etc/apt/sources.list.d$
Тут команда pip freeze выведет сразу:
argparse==1.2.1
distribute==0.6.24
wsgiref==0.1.2
Не надо удалять эти пакеты! Без них окружение работать НЕ БУДЕТ!
Можно немного допилить окружение, для этого в каталогеbin
нужно отредактировать файл activate
nano /var/www/.virtualenv/new_end/bin/activate
Добавим в самое начало строку:
export DJANGO_SETTINGS_MODULE='project.settings'
Те, кто пользуется Django, сразу поняли, что произошло. Если Вы не поняли, объясняю: эта переменная указывает, где искать файл настроек для Django-проекта. После этого нужно выйти из окружения командой
deactivate
и активировать снова.
Настройка Apache 2
Апач поставлен, но т.к. он ставился после Nginx, он не сможет запуститься, т.к. порт 80 уже занят для прослушивания. Делаем так:
nano /etc/apache2/ports
Тут должны присутствовать вот такие строки:
ServerName debian.lo
NameVirtualHost 127.0.0.1:8080
Listen 127.0.0.1:8080
Вместо debian.lo можно написать хоть ololoyakrutoj, ни на что не влияет, но избавляет от сообщения об отсутствии имени при перезапуске Apache. Следующие две строки говорят, что будут использоваться виртуальные хосты, находящиеся на локалхосте на порту 8080, и слушать Apache будет только его. Тем самым убираем конфликт с Nginx.
Включаем модуль rpaf (wsgi включает себя сам):
a2enmod rpaf
Также следует немного подредактировать его настройки:
nano /etc/apache2/mods-available/rpaf.conf
<IfModule rpaf_module> RPAFenable On RPAFsethostname Off RPAFproxy_ips 127.0.0.1 ::1 RPAFheader X-Real-IP </IfModule>Можно включить модуль сжатия данных deflate (если выключен) и настоятельно рекомендуется включить модуль rewrite (по умолчанию выключен):
a2enmod deflate
a2enmod rewrite
Следует подкрутить также загрузчик модуля wsgi:
nano /etc/apache2/mods-avaliable/wsgi.load
Там будет написано нечто подобное:
LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi_2.7.so
Если используется Python2.6, следует изменить 7 на 6, иначе опять будем получать ошибку no module named django.core.handlers.wsgi
. Добавим виртуальный хост Apache:
nano /etc/apache2/sites-available/new_site.ru
В этот файл записываем примерно следующее:
<VirtualHost 127.0.0.1:8080> ServerName new_site.ru ServerAlias www.new_site.ru ServerAdmin mymail@domen.ru WSGIScriptAlias / /var/www/my_project/my_project.wsgi WSGIProcessGroup my_project WSGIDaemonProcess my_project user=xphoenix group=xphoenix threads=2 maximum-requests=1000 DocumentRoot "/var/www/my_project" <Directory "/var/www/my_project"> Order allow,deny Allow from all </Directory> FileETag none <Location "/"> Order deny,allow Allow from all </Location> # Сжатие трафика <Location /> SetOutputFilter DEFLATE BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary </Location> </VirtualHost>
Этот виртуальный хост будет обрабатывать запросы к сайтам new_site.ru и www.new_site.ru (что одно и то же), для запуска проекта будет использоваться файл /var/www/my_project/my_project.wsgi
Для обработки запросов будет использоваться два потока (рекомендуется ставить по числу ядер), процесс будет работать в группе my_project
, запускаться от имени пользователя xphoenix. Дальнейшие директивы, в принципе, понятны.
Включаем сайт в apache:
a2ensite new_site.ru
Создадим вышеуказанный файл запуска приложения:
nano /var/www/my_project/my_project.wsgi
со следующим содержимым
#!encoding=utf-8 import os activate_this = '/var/www/.virtualenvs/new_env/bin/activate_this.py' execfile(activate_this, dict(__file__=activate_this)) os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()
Теперь можно перезапустить apache:
service apache2 restart
Настройка Nginx
Nginx будет проксировать запросы, приходящие на 80-й порт с любого интерфейса. Если это будет запрос статики, он сам его обработает, если нет, переадресует Apache. Создадим настройки для нашего сайта:
nano /etc/nginx/conf.d/my_site.conf
со следующим содержимым:
server {
listen *:80; #слушать порт 80 на всех интерфейсах
server_name new_site.ru www.new_site.lo; #этот сервер будет обрабатывать эти сайты
access_log off; #не хочу собирать общую статистику доступа
error_log /var/www/my_project/log/nginx_error.log; #А вот ошибки - да
location / {
proxy_pass http://127.0.0.1:8080/; #Переадресация запросов к Apache
proxy_set_header Host $http_host; #Подкорректируем заголовки, чтобы отличать одного клиента от другого
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_connect_timeout 120;
proxy_send_timeout 120;
proxy_read_timeout 180;
}
location ~* \.(jpg|jpeg|gif|png|ico|css|bmp|swf|js|html|txt|exe|pdf|djvu|doc|docx|xls|xlsx)$ {
root /var/www/my_project;
access_log /var/www/my_project/log/nginx_static.log;#Статистика по статике здесь
expires max; #Срок жизни кеша - максимальный
}
}
Вот теперь можно перезапустить и nginx
service nginx restart
При подключении nginx будет отдавать все файлы указанных расширений сам, а остальные запросы направлять к Apache, значительно разгружая нагрузку на него. Буду рад любой критике в комментариях.
Apache не читает .htaccess
Столкнулся с тем, что Apache читает файл .htaccess
, который я создал для своего сайта, но совершенно его не воспринимает. Длительное чтение статей выявило, что недостаточно полно был настроен файл конфигурации Apache httpd.conf
. В этой статье я расскажу, что было сделано не так, и что нужно сделать. Все операции требуют привилегий root.
Содержимое файла .htaccess
:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
Эти директивы должны были бы перенаправлять все запросы к сайту с любой страницы на index.php
, однако на самом деле этого не происходило и я получал сообщение Error 404: Page not found
. Отходить от шаблона проектирования Front Controller я не собирался, поэтому начал читать.
В большинстве статей написано, что нужно раскомментировать следующие строки в httpd.conf
:
LoadModule rewrite_module modules/mod_rewrite.so
В CentOS 6 эта строка раскомментирована по умолчанию, и нужная библиотека также присутствует в каталоге файлов Apache. В Deb-дистрибутивах этот мод по умолчанию выключен, включается командой:
a2enmod rewrite
Дальше нужно проверить, что в httpd.conf
раскомментированы следующие строки:
AccessFileName .htaccess
#Какой-то текст, куча комментариев...
<Files ~ "^\.ht">
Order allow,deny
Deny from all
Satisfy All
</Files>
Однако и этого недостаточно. По-умолчанию в качестве DocumentRoot
для Apache указана папка /var/www/html
. Соответствующие правила ее обработки описаны в httpd.conf
следующими строками (комментарии удалены):
<Directory "/var/www/html">
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
Я выкладываю сайты на свой сервер в папку /var/www
, т. е. по факту у меня DocumentRoot'ом будет выступать именно она, а не /var/www/html
. Это дело привычки, просто потом при заполнении файлов конфигурации виртуальных хостов писать текста немного меньше.
Добавим в httpd.conf
следующее:
<Directory "/var/www">
Options Indexes +FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
Не забудьте перезапустить Apache:
Debian
service apache2 restart
CentOS
service httpd restart
Теперь при вводе в адресной строке URI типа http://site.lo/Login/Auth
сервер будет перенаправлять запрос на index.php
, а тот, в свою очередь, будет вызывать метод Auth контроллера Login, но это уже совсем другая история.
Настройка vsftpd в Debian 7
В этой статье я расскажу, как настроить vsftpd в Debian 7. Все действия делаются от имени root.
ПРЕДУПРЕЖДЕНИЕ: протокол FTP не является безопасным, поэтому лучше его не использовать вовсе. Самое лучшее решение данной проблемы - SFTP, который нативно поддерживается openssh-сервером в Debian. В качестве клиента для Windows рекомендую WinScp.
Установка
apt-get install vsftpd
Основной файл настроек лежит прямо в каталоге /etc
. Отредактируем его:
vim /etc/vsftpd
В итоге файл должен выглядеть примерно так:
listen=YES #Слушать по протоколу IPv4, для IPv6+IPv4 - настройка в самом конце, закомментирована
anonymous_enable=NO #Запретить анонимный доступ
local_enable=YES #Разрешить входить по системной записи
write_enable=YES #Разрешить запись
dirmessage_enable=YES #Разрешить сообщения при смене директории
use_localtime=YES #Использовать локальное время сервера
xferlog_enable=YES #Вести лог загрузок и закачек
connect_from_port_20=YES #Осуществлять передачу данных через 20-ый порт (для безопасности)
ftpd_banner=Welcome to virtual FTP service. #Сообщение-приветствие сервера
#Если включено, то email'ы из указанного файла будут запрещены для анонимного доступа
#banned_email_file=/etc/vsftpd.banned_emails
chroot_local_user=YES #Пользователи "заперты" в своих домашних каталогах
#Настройки ниже нужно включить, если необходимо закрыть только некоторых пользователей
#в их домашних каталогах. Список будет храниться в файле, указанном в параметре chroot_list_file
#
#chroot_local_user=YES
#chroot_list_enable=YES
# (default follows)
#chroot_list_file=/etc/vsftpd.chroot_list
# You may activate the "-R" option to the builtin ls. This is disabled by
# default to avoid remote users being able to cause excessive I/O on large
# sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
# the presence of the "-R" option, so there is a strong case for enabling it.
#ls_recurse_enable=YES
#
# Customization
#
# Some of vsftpd's settings don't fit the filesystem layout by
# default.
#
# This option should be the name of a directory which is empty. Also, the
# directory should not be writable by the ftp user. This directory is used
# as a secure chroot() jail at times vsftpd does not require filesystem
# access.
secure_chroot_dir=/var/run/vsftpd/empty
#
# This string is the name of the PAM service vsftpd will use.
pam_service_name=vsftpd
#
# This option specifies the location of the RSA certificate to use for SSL
# encrypted connections.
rsa_cert_file=/etc/ssl/private/vsftpd.pem
#По-умолчанию эта опция имеет значение YES, и vsftpd проверяет, что у подключившегося пользователя
#в системе есть валидный shell. Если shell имеет значение false или не определен, вход на сервер
#будет отклонен с сообщением Invalid password
check_shell=NO
Перезапускаем:
service vsftpd restart
Для проверки работоспособности сервера можно подключиться к нему командой
ftp localhost
Если программа ftp не установлена, ее можно установить командой
apt-get install ftp
Сервер запросит пароль, и если всё указано верно, то будет осуществлён вход под текущей учётной записью.
Apache Virtual Host в CentOS (виртуальные хосты Apache)
В данной статье будет рассказано о том, как настроить Apache в CentOS и разместить несколько сайтов, используя виртуальные хосты. Все операции имеет право делать только root.
Начнем с того, что в CentOS Apache называется httpd, и, соответственно, команда для установки имеет следующий вид:
yum install httpd
Нас спросят, действительно ли мы хотим этим заняться. Отвечаем y (Yes). Можно было написать и так:
yum install httpd -i
Добавим его в автозагрузку:
chkconfig httpd on
Все операции с демоном httpd осуществляются командой
/etc/init.d/httpd %команда%
или так
service httpd %команда%
Например, так можно перезапустить сервис:
service httpd restart
Список доступных команд можно посмотреть вот так:
service httpd
Все настройки Apache в CentOS хранятся в подкаталогах каталога /etc/httpd
В каталоге conf
находится главный конфигурационный файл - httpd.conf
.
Рассмотрим только основные опции, которые необходимы. Все, о чем здесь не будет сказано, оставляем по-умолчанию.
Директива Listen
указывает, какие порты будет слушать сервер. По умолчанию там стоит значение 80, т. е. все соединения идут с 80-го порта (мировой стандарт, если что). Если у нас специфическая ситуация, то можно поменять это значение, либо добавить другие порты, написав, например, следующее:
Listen 80
Listen 81
Listen 192.168.1.25:82
Что, собственно, здесь происходит? Listen 81
указывает, что нужно слушать также и 81 порт. Строка Listen 192.168.1.25:82
заставляет сервер прослушивать запросы, приходящие с сетевого интерфейса с адресом 192.168.1.25 через 82-ой порт.
В строке
Include conf.d/*.conf
говорится, что нужно также загрузить параметры из всех файлов с расширением .conf
, находящихся в каталоге conf.d
. Забегая вперед замечу, что файлы конфигураций сайтов мы будем размещать именно там.
ServerAdmin root@localhost
указывает, кто будет получать сообщения об ошибках сервера на почту. Для каждого сайта это значение потом можно будет переопределить (типичная ситуация, когда на одном физическом сервере находится несколько сайтов разных владельцев).
DirectoryIndex index.html index.html.var
указывает, в каком порядке искать страницы сайта, если пользователь ввел только адрес. Немного модифицируем эту строку для разработки на php:
DirectoryIndex index.php index.html index.html.var
Строки для языков у меня стерты все, за исключением двух:
AddLanguage en .en
AddLAnguage ru .ru
и соответственно
LanguagePriority ru en
Снимаем комментарий вот тут:
AddDefaultCharset UTF-8
и вот тут
NameVirtualHost *:80
Для тех, кто собирается программировать на Python, используя Django, рекомендую добавить в самом конце строку
WSGIRescrictStdout Off
Перейдем в каталог /etc/httpd/conf.d/
.
Здесь мы видим несколько файлов с расширением .conf
. Обычно там лежат default.conf
, welcome.conf
и php.conf
(если уже установили PHP). Для добавления нового сайта достаточно скопировать
default.conf
и немного изменить его:cp default.conf mysite.conf
vim mysite.conf
Внутри файла достаточно написать следующее:
<VirtualHost *:80>
ServerName www.demo1.ru
ServerAlias demo1.ru
ServerAdmin admin@otheremail.com #Указываем адрес администратора этого сайта
DocumentRoot "/var/www/demo1"
<Directory "/var/www/demo1">
Order allow,deny
Allow from all
</Directory>
LogLevel debug #По умолчанию для всего сервера стоит значение warn, т. е. писать в лог только события не ниже предупреждения. Для разработчиков сайтов я рекомендую ставить именно debug
ErrorLog "/var/www/demo1/log/apache_error.log" #Эти две директивы необязательны, но они помогут разобраться, какие ошибки происходят на сайте
CustomLog "/var/www/demo1/log/apache_access.log" combined #Лог с запросами к серверу: страницы, ресурсы и т. д.
#FileETag none
</VirtualHost>
Также рекомендую добавить следующую запись в настройки виртуального хоста:
Alias / "/var/www/demo1"
Тем самым мы указываем, какую директорию считать корнем сайта.
Внимание! Каталог /var/www/demo1/log/
должен существовать, иначе при перезапуске apache выдаст сообщение об ошибке и откажется стартовать!
После всего этого перезагружаем конфигурацию apache (быстрее, чем полный перезапуск с параметром restart
, особенно если с сайтом работают клиентские машины):
/etc/init.d/httpd reload
Теперь, чтобы обратиться к данному сайту по адресу, необходимо прописать сопоставление в файле hosts
Linux: /etc/hosts
Windows: C:\Windows\System32\Drivers\etc\hosts
Любым текстовым редактором добавляем туда строки (у меня адрес сервера 192.168.1.1):
192.168.1.1 demo1.lo
192.168.1.1 www.demo1.lo
Теперь, когда я буду вводить в строке браузера demo1.lo, он будет автоматически запрашивать на сервере нужное содержимое.
Обратите внимание, по умолчанию apache ищет в каталоге сайта файл index.html
.
Настройка vsftpd в CentOS
Я расскажу, как настроить доступ к FTP авторизованным пользователям в CentOS 6.4 (статья давно не обновлялась, а т.к. я прочно перешёл на Debian, то ждать переписывания не стоит).
Все операции делаются от имени root.
-
Установка
yum install -i vsftpd
-
После установки нужно добавить нужный демон в автозагрузку:
chkconfig vsftpd on
-
Откроем основной файл настроек (новички вместо vim могут использовать nano)
vim /etc/vsftpd/vsftpd.conf
-
Для начала закроем анонимный доступ:
anonymous_enable=NO
-
Открыть доступ авторизованным пользователям:
local_enable=YES
-
Разрешить запись:
write_enable=YES
-
Можно написать что угодно, это служебное сообщение, которое выводится при подключении к данному серверу:
ftpd_banner=Welcome to my FTP-server!
-
Сохраняем изменения и перезапускаем службу:
/etc/init.d/vsftpd restart
-
Следует учесть, что если нужно дать доступ в систему пользователю, у которого нет валидного shell'а, следует указать его shell как nologin командой
usermod --shell /sbin/nologin %имя_пользователя%
В противном случае при попытке входа на FTP пользователь будет получать ошибку автризации.
-
Если в системе используется SELinux, то нужно разрешить несколько действий нашему демону:
setsebool -P allow_ftpd_full_access on setsebool -P ftp_home_dir on
Ключ -P используется для того, чтобы настройки сохранились после перезагрузки.
Установка и настройка ProFTPd в Ubuntu
I. Установка и настройка сервера.
Все действия производятся от имени root.
-
Ставим:
apt-get install proftpd
-
Указываем, как запускать, через inetd (маленькая нагрузка) или самостоятельно (десятки пользователей). Если выбрать inetd, то сервер, скорее всего, не стартанёт. Этот глюк был замечен мной и на Ubuntu Server 12.04.1, и на Debian 6.0.6. Если у вас то же самое, то смотрите ниже.
vi /etc/proftpd/proftpd.conf
Если надо, переименовываем сервер:
ServerName "Ultimate Super Mega FTP Server"
Меняем ServerType, если он не запускается как демон inetd
ServerType standalone
Раскомментируем вот эту строку, чтобы разрешить пользователям работать только в своих домашних каталогах.
DefaultRoot ~
Разрешаем пользователям пользоваться FTP, даже если им запрещено логиниться в системе:
RequireValidShell off
-
После всех настроек не забываем перезапустить демон proftpd
/etc/init.d/proftpd restart
Также работает команда
service proftpd restart
Сервер готов к использованию.
Добавление пользователей.
У нас есть рабочий FTP-сервер, необходимо добавить его пользователей. Пусть все они, для удобства, хранят свои данные в каталоге /var/ftp/%имя_пользователя%
. Добавим одного такого пользователя, создав для подобных ему группу ftp_users
.
-
Создадим группу:
addgroup ftp_users
-
Добавим пользователя
ftp01
, указав расположение его домашнего каталога, оболочку, запрет на вход в систему и группу.adduser ftp01 --home /var/ftp/ftp01 --shell /bin/false --disabled-login --ingroup ftp_users
-
Зададим пароль свежесозданному пользователю (на экране не будет видно ничего, даже звездочек):
passwd ftp01 Password: Confirm password: Password succesfully changed.
Установка и настройка PostgreSQL в CentOS
По-умолчанию в CentOS 6.4 идет Postgresql версии 8.4. Нам не надо такую старую, поэтому первым делом нужно добавить официальный репозиторий и запретить установку старых пакетов. Все операции выполняются под root'ом.
Идем сюда и смотрим ссылку на последнюю стабильную версию для CentOS. На момент написания статьи это была версия 9.2, ссылка на пакет была такой
Скачиваем его командой wget
:
wget http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/pgdg-centos92-9.2-6.noarch.rpm
Если система выдает сообщение, что wget
- неизвестная команда, его нужно установить:
yum install wget -y
После успешной установки повторяем запрос. Итак, Файл репозитория скачался, пора его импортировать:
rpm -i pgdg-centos92-9.2-6.noarch.rpm
Теперь необходимо запретить системе устанавливать старые пакеты из стандартного репозитория. Открываем любым редактором файл /etc/yum.repos.d/CentOS-Base.repo
и добавляем в секции [base]
и [updates]
строку
exclude=postgresql*
Должно получиться примерно так (комментарии удалены):
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
exclude=postgresql*
[updates]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
exclude=postgresql*
[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
[centosplus]
name=CentOS-$releasever - Plus
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus
#baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
[contrib]
name=CentOS-$releasever - Contrib
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=contrib
#baseurl=http://mirror.centos.org/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Теперь нужно обновить локальную копию списка пакетов:
yum update
А вот теперь можно установить сервер:
yum install postgresql92-server -y
Теперь сервер нужно настроить. Инициализируем его:
service postgresql-9.2 initdb
и добавим в автозагрузку:
chkconfig postgresql-9.2 on
Все настройки сервера хранятся в каталоге /var/lib/pgsql/9.2/data/
. Отредактируем файл pg_hba.conf
vim /var/lib/pgsql/9.2/data/pg_hba.conf
В этом файле несколько строк, которые отвечают за параметры доступа к серверу. Следует обратить внимание на строку
local all all ident
Не вдаваясь в детали скажу, что эта строка разрешает подключение локальных пользователей к серверу без ввода логина и пароля, если пользователь авторизован в системе. Пока не будем ничего менять, вернемся сюда позже. Сейчас нужно войти в систему под именем пользователя postgres:
su postgres
Запускаем оболочку psql
bash-4.1$ psql
Нас пускают без ввода пароля, выдавая окно приветствия:
psql (9.2.4)
Введите "help", чтобы получить справку.
postgres=#
Зададим пользователю postgres пароль, чтобы иметь возможность более простым способом авторизоваться в СУБД. Ввод точки с запятой в конце команды обязателен.
ALTER ROLE postgres WITH PASSWORD 'postgres';
Система ответит:
ALTER ROLE
Можно покинуть интерпретатор, для этого вводим в консоли команду
postgres=# \q
Выходим из-под пользователя postgres:
bash-4.1$ exit
Теперь внесем изменения в вышеуказанный файл pg_hba, приведя его примерно к такому виду:
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
host all all 192.168.1.2/32 md5
Первая строка разрешает подключение к СУБД для всех локальных пользователей, но при этом требует с них ввод пароля. Вторая делает практически то же самое, но мы эту строку оставим для того, чтобы подключаться к СУБД могли даже те пользователи, у кого нет системной учетной записи, а есть только роль в СУБД. Например, Вы добавили несколько баз данных и указали для них владельцев, но при этом не хотите, чтобы они имели возможность входить в систему. При этом эти люди не будут ограничены в работе со своей базой данных.
Последняя строка разрешает подключаться к любой базе любому пользователю с адреса 192.168.1.2
, требуя взамен логин и пароль. Чтобы эта настройка работала, необходимо в файле postgresql.conf
раскомментировать и изменить строку
#listen_addresses = 'localhost'
на
listen_addresses = '*'
Это заставит СУБД слушать все сетевые интерфейсы в поисках входящих подключений. Удобно (и очень опасно), если Вы хотите управлять СУБД через pgAdmin удаленно. Остальные настройки можно оставить по-умолчанию.
Перезапускаем службу:
service postgresql-9.2 restart
Если всё нормально, видим:
Останавливается служба postgresql-9.2: [ OK ]
Запускается служба postgresql-9.2: [ OK ]
Пробуем подключиться от имени пользователя postgres:
psql -U postgres
Поздравляю! Можете приступать к изучению консольных команд PostgreSQL. В самом простом случае Вам нужно будет создать пользователя СУБД и добавить для него базу данных. Запустите интерпретатор psql
:
psql -U postgres
Введите команды:
CREATE ROLE abcd WITH PASSWORD 'dcba' LOGIN;
CREATE DATABASE aabbccdd WITH OWNER abcd;
Вы только что создали пользователя abcd
с паролем dcba
, разрешили ему вход в СУБД и добавили базу данных, указав, что ее владельцем является этот новый пользователь, т. е. он имеет все необходимые привилегии для работы с этой базой. Если захотите подключиться к БД aabbccdd
от имени пользователя abcd
, введите в консоли команду psql
с вот этими ключами:
psql -U abcd -d aabbccdd
Если не указать ключ -d
и имя БД следом за ним, PostgreSQL попытается подключиться к БД с тем же названием, что и имя текущего пользователя, не найдет ее и выдаст сообщение об ошибке.
Комментариев нет :
Отправить комментарий