суббота, 16 марта 2013 г.

Pyramid + virtualenv + UWSGI + nginx на FreeBSD

В этой заметке описывается настройка связки Pyramid + UWSGI + nginx + python3.2 в двух вариантах: virtualenv и uwsgi-plugins на хостинге FreeBSD. Надо отметить, что по-умолчанию на сервере используется python2.7.

I. virtualenv

Для начала надо установить python3.2 и необходимые дополнительные пакеты:
make -C /usr/ports/lang/python32 install clean
make -C /usr/ports/databases/py-sqlite3 PYTHON_VERSION=python3.2 NO_PKG_REGISTER=yes install
(NO_PKG_REGISTER необходим для обхода конфликта с уже установленными версиями для дефолтного python2.7)
make -C  /usr/ports/devel/py-distribute PYTHON_VERSION=python3.2 NO_PKG_REGISTER=yes install
pip-3.2 install virtualenv

Затем необходимо создать окружение для пользователя, из под которого будет работать сайт:
su user
cd
virtualenv-3.2 --system-site-packages env

и установить локальный uwsgi:
env/bin/pip install uwsgi

Клонируем сайт из репозитория gitolite:
git clone git@127.0.0.1:/project.git

Далее надо настроить uwsgi (project.yaml):
uwsgi:
  chdir: /www/user/project
  virtualenv: /www/user/env
  uid: user
  gid: user
 # указываем socket, при помощи которого будет происходить
 # взаимодействие между nginx и uwsgi
  socket: /tmp/project_uwsgi.sock
 # здесь указываем путь к проекту
   pythonpath: /www/user/project
# путь к лог файлу
  daemonize: /www/user/log/uwsgi.log
 # прочие настройки, значения который можно посмотреть на сайте uWSGI
  max-requests: 5000
  buffer-size: 32768
  harakiri: 30
  reload-mercy: 8
  master: 1
  no-orphans: 1
 # если выполнить команду "touch <имя ниже указанного файла>",
 # то произойдет перезапуск uwsgi демона.
  touch-reload: /www/user/uwsgi
  paste: config:/www/user/project/production.ini

Конфиг nginx:
server {
  listen 80;
 
  server_name project.ru www.project.ru;

  access_log /www/user/log/access;
  error_log /www/user/log/error;

  root /www/user/project/;

  location / {
 # ниже надо указать путь к socket'у, при помощи которого
 # nginx и uwsgi будут сообщаться.
 # в данном случае путь это '/var/tmp/odmin4eg_uwsgi.sock'
  uwsgi_pass unix:///tmp/user_uwsgi.sock;
 include uwsgi_params;
 uwsgi_param SCRIPT_NAME /;

 # 8 -- число буфферов
 # 128k -- размер буфера
  # фактически, мы сможем передать от project в nginx только 1 мб информации.
 # играйтесь с этим значением при поднятии своего проекта
 uwsgi_buffers 8 128k;
 }

 location /static/ {
 # а вот здесь указываем абсолютный путь к директории со
 # статическими файлами
  alias /www/user/project/www/static/;
 expires 30d;
 }
}

II. uwsgi plugin

cd /usr/ports/uwsgi
make
cd work/uwsgi-1.2.4/
echo "plugin_dir = /usr/local/lib/uwsgi" >> buildconf/core.ini
python uwsgiconfig.py --clean
python uwsgiconfig.py --build core
python uwsgiconfig.py --plugin plugins/python core python27
python32 uwsgiconfig.py --plugin plugins/python core python32
здесь возможно потребуется пересобрать Python3.2: make -C /usr/ports/lang/python32/ CFLAGS=-fPIC deinstall install
cd /usr/ports/uwsgi
make install

pip-3.2 install PasteDeploy pyramid pyramid-debugtoolbar pyramid-tm waitress zope.sqlalchemy
Возможна такая ситуация при запуске uwsgi: Traceback (most recent call last):
  File "/usr/local/lib/python3.2/site-packages/paste/deploy/loadwsgi.py", line 247, in loadapp
    return loadobj(APP, uri, name=name, **kw)
  File "/usr/local/lib/python3.2/site-packages/paste/deploy/loadwsgi.py", line 271, in loadobj
    global_conf=global_conf)
  File "/usr/local/lib/python3.2/site-packages/paste/deploy/loadwsgi.py", line 277, in loadcontext
    if '#' in uri:
TypeError: Type str doesn't support the buffer API
Тогда надо добавить в /usr/local/lib/python3.2/site-packages/paste/deploy/loadwsgi.py перед строкой 277 содержащей if '#' in uri: if isinstance(uri, bytes):
        uri = uri.decode('utf-8')



Ссылки:
http://projects.unbit.it/uwsgi/wiki/Guide4Packagers
http://projects.unbit.it/uwsgi/wiki/MultiPython
http://liangsun.org/network/pyramid-nginx-uwsgi-mysql/