Debian, Dojo, Django, Python

Делюсь опытом в описанных технологиях. Блог в первую очередь выполняет роль памяток для меня самого.

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.conf
user 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)

Комментариев нет
Данная статья рассказывает о том, как правильно собрать PIL для поддержки различных форматов.

Описание проблемы

Несмотря на то, что уже давно существует и активно развивается библиотека 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 на боевых серверах. Будет использовано следующее ПО:

  1. Python 2.6. Вы можете использовать вообще любой, какой Вам нравится, просто проекты, которыми пользуется моя организация, используют именно его. По умолчанию в Debian 7 установлен Python 2.7, но без проблем можно установить и более старую версию. Проблем с 3-ей версией также не возникнет, он есть в стандартных репозиториях.
  2. Virtualenv и virtualenvwrapper. Благодаря этим пакетам можно создать свою песочницу для каждого проекта Django, указав свой собственный интерпретатор Python (2.6, 2.7, 3, 3.1 - и всё на одной машине) и набор пакетов (а также версий пакетов). Данное ПО позволяет изолировать проекты друг от друга, при необходимости используя разные версии библиотек. Допустим, в одном проекте используется lxml версии 2.3.1, а в другом 3.2.1. Как быть? Просто добавляем в одно окружение 2.3.1, а в другое - 3.2.1, и никаких конфликтов библиотек не будет.
  3. Gunicorn. Этот легковесный сервер позволяет размещать на одном сервере проекты, использующие разные версии Python. В отличие от apache2-mod-wsgi, он позволяет работать одновременно и с Python2.6, и с Python2.7 (имеется ввиду разделение по проектам). Работа же mod-wsgi глобальна, т.е. весь сервер сразу поддерживает либо одну версию Python, либо другую.
  4. Supervisor. Эта утилита позволяет демонизировать процессы. В рассматриваемом случае она будет запускать gunicorn-серверы проектов. Некоторые скажут, что можно использовать init. Пожалуйста, я никого не заставляю, но настроек для init'а у меня нет.
  5. PostgreSQL. Наиболее продвинутая из бесплатных и максимально соблюдающая SQL-стандарты из известных мне СУБД. С помощью утилиты pgtune можно в автоматическом режиме оптимизировать настройки (содержимое файла postgresql.conf) под конкретную машину с учётом размера оперативной памяти, дискового кэша и т.д.
  6. Nginx. В представлении не нуждается. Самый производительный web-сервер в мире на сегодня.
  7. Пакеты для работы с графикой, XML и сборки драйвера psycopg2 PostgreSQL для Python (ставить желательно, но не обязательно):
    • libfreetype6-dev - позволяет Pillow выводить надписи на изображения
    • zlib1g-dev - включает поддержку PNG-формата для Pillow
    • libjpeg8-dev - позволяет Pillow обрабатывать JPEG-изображения
    • libwebp-dev - позволяет Pillow работать с форматом webp
    • libtiff-dev - комментарии излишни
    • liblcms2-dev - для поддержки библиотеки управления цветовыми профилями Little Color Management System версии 2.
    • libpq-dev - без этого пакета в виртуальном окружении не соберётся пакет psycopg2, необходимый для использования PostgreSQL
    • libxml2-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 приходится всё допиливать под себя.

  1. Огромное количество пакетов. Я не знаю, есть ли где-то ещё больше. Если есть - напишите мне.
  2. Python 2.6 в официальном репозитории. Да, Debian 7.1 не требует возни с дохлыми змеями.
  3. Под него есть официальные сборки PostgreSQL и Nginx. Я раньше тоже думал, что MySQL наше всё, а сейчас вообще не понимаю, как можно пользоваться этой поделкой, не соблюдающей 90% мировых SQL-стандартов. Да, если вы пишете скрипты, руководствуясь SQL-92 или SQL-99, можете быть уверены, что в PostgreSQL они будут работать без каких-либо изменений, в то время как в MySQL их придётся переписывать, и весьма основательно (к слову, в разработке PostgreSQL принимают участие несколько профессоров математики и информатики, что как бы говорит о качестве получающегося продукта).
  4. Стабильность. Пакеты старые, но если они есть в репозитории, то можно не сомневаться, что они будут работать так, как то ожидается.

Немного про виртуальные окружения

Пакет 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 - опционально, если используется модуль psycopg2
  • python-pip - опционально, для установки пакетов Python, распространяемых в исходных кодах. Рекомендую в систему ставить пакет из репозиториев Debian, а в виртуальные окружения через easy_install pip
  • python-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.

  1. Установка

    yum install -i vsftpd
  2. После установки нужно добавить нужный демон в автозагрузку:

    chkconfig vsftpd on
  3. Откроем основной файл настроек (новички вместо vim могут использовать nano)

    vim /etc/vsftpd/vsftpd.conf
  4. Для начала закроем анонимный доступ:

    anonymous_enable=NO
  5. Открыть доступ авторизованным пользователям:

    local_enable=YES
  6. Разрешить запись:

    write_enable=YES
  7. Можно написать что угодно, это служебное сообщение, которое выводится при подключении к данному серверу:

    ftpd_banner=Welcome to my FTP-server!
  8. Сохраняем изменения и перезапускаем службу:

    /etc/init.d/vsftpd restart
  9. Следует учесть, что если нужно дать доступ в систему пользователю, у которого нет валидного shell'а, следует указать его shell как nologin командой

    usermod --shell /sbin/nologin %имя_пользователя%

    В противном случае при попытке входа на FTP пользователь будет получать ошибку автризации.

  10. Если в системе используется SELinux, то нужно разрешить несколько действий нашему демону:

    setsebool -P allow_ftpd_full_access on
    setsebool -P ftp_home_dir on

    Ключ -P используется для того, чтобы настройки сохранились после перезагрузки.

Комментариев нет :

Отправить комментарий

Установка и настройка ProFTPd в Ubuntu

Комментариев нет

I. Установка и настройка сервера.

Все действия производятся от имени root.

  1. Ставим:

    apt-get install proftpd
  2. Указываем, как запускать, через 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
  3. После всех настроек не забываем перезапустить демон proftpd

    /etc/init.d/proftpd restart

    Также работает команда

    service proftpd restart

    Сервер готов к использованию.

Добавление пользователей.

У нас есть рабочий FTP-сервер, необходимо добавить его пользователей. Пусть все они, для удобства, хранят свои данные в каталоге /var/ftp/%имя_пользователя%. Добавим одного такого пользователя, создав для подобных ему группу ftp_users.

  1. Создадим группу:

    addgroup ftp_users
  2. Добавим пользователя ftp01, указав расположение его домашнего каталога, оболочку, запрет на вход в систему и группу.

    adduser ftp01 --home /var/ftp/ftp01 --shell /bin/false --disabled-login --ingroup ftp_users
  3. Зададим пароль свежесозданному пользователю (на экране не будет видно ничего, даже звездочек):

    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 попытается подключиться к БД с тем же названием, что и имя текущего пользователя, не найдет ее и выдаст сообщение об ошибке.

Комментариев нет :

Отправить комментарий