python

Vesta CP: установка веб-приложений на Ruby и Python

  • суббота, 14 марта 2015 г. в 02:10:48
http://habrahabr.ru/post/252955/



Привет Хабр.
Я люблю, когда все лежит на своих местах, все в чистоте и порядке.
Поэтому раз в квартал разгребаю творческий беспорядок. ®
Для меня важно иметь стабильную ОС с уверенностью в том, что после очередного ежедневного обновления ничего не сломается. Многие разработчики выбирают ОС исходя из наличия актуальных версий софта. Я умею готовить Centos и в "yum -y install yum-cron" уверен на 99.98%.

Расскажу, как при этом можно использовать последние версии ruby и python для web-разработки. Так же по результатам на сервере будут установлены 4 веб-приложения от одного регулярного пользователя: djangocms (python 3.4.3 ), quokka (python 2.7.9 ), redmine (ruby 2.2.1 ), refinerycms (ruby 2.0.0). На тонкие параметры запуска приложения внимание обращено не будет (выбор БД, количество веркеров, соединений, логи и т.д.). Хотел описать LocomotiveCMS, но оно оказалось паровозом с кучей ручных правок для сетапа.

Для комфорта и удобства будем использовать панель управления VestaCP. Потому что она просто великолепна и идеологически родная.

Подготовка системы


Итак, у нас есть тестовая VPS с Centos 6, root доступ. Вопреки официальному руководству будем ставить панель с опцией "-d".

curl -O http://vestacp.com/pub/vst-install.sh
bash vst-install.sh -d

Таким образом, мы ограничим установку только «epel» репозиторием, без «remi» (т.е. без последних версий mysql и php).
Добавляем темплейты доменов для nginx:

cat > /usr/local/vesta/data/templates/web/nginx/socket.tpl...
cat > /usr/local/vesta/data/templates/web/nginx/socket.tpl << EOF
upstream %domain%_app_server {
  server unix:/tmp/%domain%.sock fail_timeout=0;
}
server {
    listen      %ip%:%proxy_port%;
    server_name %domain_idn% %alias_idn%;
    error_log  /var/log/httpd/domains/%domain%.error.log error;
    access_log  /var/log/httpd/domains/%domain%.access.log;

    location /static/ {
        alias   %docroot%/static/;
    }

    location /media/ {
        alias   %docroot%/media/;
    }

    location / {
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header Host \$http_host;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_redirect off;
        if (!-f \$request_filename) {
            proxy_pass http://%domain%_app_server;
            break;
        }
    }
    include %home%/%user%/conf/web/nginx.%domain%.conf*;
}
EOF
cat > /usr/local/vesta/data/templates/web/nginx/socket.stpl << EOF
server {
    listen      %ip%:%proxy_ssl_port%;
    server_name %domain_idn% %alias_idn%;
    ssl         on;
    ssl_certificate      %ssl_pem%;
    ssl_certificate_key  %ssl_key%;
    error_log  /var/log/httpd/domains/%domain%.error.log error;
    access_log  /var/log/httpd/domains/%domain%.access.log;

    location /static/ {
        alias   %sdocroot%/static/;
    }

    location /media/ {
        alias   %sdocroot%/media/;
    }

    location / {
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header Host \$http_host;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_redirect off;
        if (!-f \$request_filename) {
            proxy_pass http://%domain%_app_server;
            break;
        }
    }
    include %home%/%user%/conf/web/snginx.%domain%.conf*;
}
EOF
chown admin.admin /usr/local/vesta/data/templates/web/nginx/socket*


Далее установка пакетов: mongodb для quokka, supervisor третьей ветки, и dev-пакеты:

yum install ...
yum install mongodb-server -y
chkconfig mongod on
service mongod start

yum install http://mirror.symnds.com/distributions/gf/el/6/gf/i386/gf-release-6-6.gf.el6.noarch.rpm -y
yum --enablerepo=gf-plus install supervisor -y
chkconfig supervisord on
service supervisord start

yum groupinstall "Development tools" -y
yum install ImageMagick-devel mysql-devel zlib-devel bzip2-devel openssl-devel ncurses-devel \
    sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libjpeg-devel \
    libyaml-devel libffi-devel -y
yum install git mercurial nodejs -y


И последнее, что потребуется от root-а, это настройка supervisor-а:

cat /etc/supervisord.d/reguser.ini
[program:djangocms.test.site]
directory=/home/reguser/web/%(program_name)s/public_html
command=/home/reguser/.pyenv/shims/gunicorn -b unix:/tmp/%(program_name)s.sock project.wsgi:application
user=reguser
autostart=true
autorestart=true
redirect_stderr=true
[program:quokka.test.site]
directory=/home/reguser/web/%(program_name)s/public_html
command=/home/reguser/.pyenv/shims/gunicorn -b unix:/tmp/%(program_name)s.sock manage:app
user=reguser
autostart=true
autorestart=true
redirect_stderr=true
[program:redmine.test.site]
directory=/home/reguser/web/%(program_name)s/public_html/
#command=/home/reguser/.rbenv/shims/unicorn         -l /tmp/%(program_name)s.sock -E production
command=/home/reguser/.rbenv/shims/thin start --socket /tmp/%(program_name)s.sock -e production 
user=reguser
autostart=true
autorestart=true
redirect_stderr=true
[program:refinerycms.test.site]
directory=/home/reguser/web/%(program_name)s/public_html/
command=/home/reguser/.rbenv/shims/unicorn  -l /tmp/%(program_name)s.sock
user=reguser
autostart=true
autorestart=true
redirect_stderr=true


Вот и все, что требуется от супер-пользователя.

В Vesta добавляем пользователя (reguser), разрешаем SSH Access в bash и создаем 4 домена:
djangocms.test.site, quokka.test.site, redmine.test.site, refinerycms.test.site.
В настройках каждого домена указываем добавленный ранее профиль nginx под названием «socket».
Таким образом, nginx будет слушать unix-сокеты, которые будут создаваться супервайзером, с правами регулярного пользователя.

На страничках каждого домена будет отображаться неприятное «502 Bad Gateway» — значит, идем по правильному пути.

Настройка пользовательского окружения


Если в «системе» у нас все аккуратно, то в «хомяке» у нас будет много-много самосборного мусора.
Однако мы ничего не увидим. Для нас всю грязную работу сделают PyEnv и RbEnv.

su - reguser

Первым решим вопрос RbEnv. Многозначительная страничка rbenv.org отправит нас на гитхаб, где мы самостоятельно осознаем философию shims.

git clone https://github.com/sstephenson/rbenv.git ~/.rbenv 
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
. ~/.bash_profile
type rbenv
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

Смотрим доступные версии и собираем последние версии ветки 2.0 и 2.2:

rbenv install -l
rbenv install 2.0.0-p643
rbenv install 2.2.1

Как ни странно, но PyEnv — это форк RbEnv, подробнее тут. Выполняем почти тоже самое:

curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash
echo 'export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile
. ~/.bash_profile
pyenv install -l
pyenv install 2.7.9
pyenv install 3.4.3

Установка Redmine


Предварительно необходимо создать mysql БД в Vesta:

cd ~/web/redmine.test.site/public_html
rm -rf *
hg clone --updaterev 3.0-stable https://bitbucket.org/redmine/redmine-all .
echo 'production:
  adapter: mysql2
  database: reguser_redmine
  host: localhost
  username: reguser_redmine
  password: "password"
  encoding: utf8
' > config/database.yml

Далее очень важная строчка, она создает файл .ruby-version в текущем каталоге, тем самым указывает нужную версию shims. Тоже самое происходит и с версиями python при pyenv local x.x.x.

rbenv local 2.2.1
gem install bundler
bundle install --without development test
rake generate_secret_token
RAILS_ENV=production rake db:migrate
RAILS_ENV=production rake redmine:load_default_data
На выбор thin или unicorn (что указано в супервайзере):
gem install thin
echo 'gem "thin"' >> Gemfile
gem install unicorn
echo 'gem "unicorn"' >> Gemfile

Первый пошел. Осталось передернуть супервайзер из консоли 'supervisorctl restart redmine.test.site', или через веб морду… и редмайн готов к работе redmine.test.site:



Установка RefineryCMS


Все аналогично, с учетом официального руководства:

cd ~/web/refinerycms.test.site/public_html/
rbenv local 2.0.0-p643
gem install rails --version 4.1.8
gem install execjs
rails new . -m http://refinerycms.com/t/edge
gem install unicorn

Страница с приглашением создать администратора ждет, refinerycms.test.site/refinery:



Установка DjangoCMS


cd ~/web/djangocms.test.site/public_html
pyenv local 3.4.3
pip install djangocms-installer

Далее последует диалог. Выберите «Languages» = «en, ru», «Twitter Theme» = «yes», «with examples» = «yes». Остальное по умолчанию.

djangocms -p . project

По окончании попросят указать логин пароль и почтовый адрес.

python manage.py cms  check  # check cms
pip install gunicorn

И вот она djangocms.test.site:


Установка QUOKKA


cd ~/web/quokka.test.site/public_html
git clone https://github.com/quokkaproject/quokka .
pyenv local 2.7.9
pip install -r requirements.txt
sed -i "s|^GRAVATAR.*$|&\n    'use_ssl': True,|" quokka/settings.py
python manage.py populate
python manage.py createsuperuser
ln -s quokka/static static
pip install gunicorn

А вот и последний зверь quokka.test.site:



Стоит отметить, что в отличии от RbEnv/RVM, в PyEnv вы можете создать virtualenv. Эти вещи не взаимоисключающие.
Надеюсь, мой гайд с установками различных веб-приложений был интересен.

Спасибо.

В завершение котик