
Vesta CP: Installing Web Applications in Ruby and Python
- From the sandbox
- Tutorial

Hi Habr.
I love when everything lies in its place, everything is clean and tidy.It is important for me to have a stable OS with the confidence that after the next daily update, nothing will break. Many developers choose the OS based on the availability of current software versions. I can cook Centos and I am 99.98% sure in " yum -y install yum-cron ".
Therefore, once a quarter I rake in a creative mess.
I’ll tell you how you can use the latest versions of ruby and python for web development. Also, according to the results, 4 web applications from one regular user will be installed on the server: djangocms (python 3.4.3), quokka (python 2.7.9), redmine (ruby 2.2.1), refinerycms(ruby 2.0.0). No attention will be paid to the thin application launch parameters (database selection, number of werkers, connections, logs, etc.). I wanted to describe LocomotiveCMS, but it turned out to be a steam locomotive with a bunch of manual edits for the setup.
For comfort and convenience we will use the VestaCP control panel. Because she is simply magnificent and ideologically dear.
System preparation
So, we have a test VPS with Centos 6, root access. Contrary to the official leadership, we will put the panel with the option "-d".
curl -O http://vestacp.com/pub/vst-install.sh
bash vst-install.sh -d
Thus, we will limit the installation to only “epel” repository, without “remi” (ie without the latest versions of mysql and php).
Add domain templates for 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*
Further installation of packages: mongodb for quokka, supervisor of the third branch, and dev-packages:
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
And the last thing that is required from root is setting up a 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
That's all that is required of a super user.
In Vesta, add a user (reguser), enable SSH Access in bash and create 4 domains:
djangocms.test.site , quokka.test.site , redmine.test.site , refinerycms.test.site .
In the settings of each domain, specify the nginx profile added earlier under the name “socket”.
Thus, nginx will listen to unix sockets that will be created by the supervisor with regular user rights.
On the pages of each domain an unpleasant “502 Bad Gateway” will be displayed - which means we are going the right way.
Customization of user environment
If everything is neat in the "system", then in the "hamster" we will have many, many self-assembled garbage.
However, we will not see anything. For us, all the dirty work will be done by PyEnv and RbEnv.
su - reguser
The first to solve the issue is RbEnv. A significant page of rbenv.org will send us to the github, where we will independently recognize the shims philosophy.
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
We look at the available versions and collect the latest versions of branches 2.0 and 2.2:
rbenv install -l
rbenv install 2.0.0-p643
rbenv install 2.2.1
Oddly enough, but PyEnv is a fork of RbEnv, more details here . We do almost the same thing:
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
Install Redmine
First you need to create a mysql database in 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
Further, a very important line, it creates a .ruby-version file in the current directory, thereby indicating the desired version of shims. The same thing happens with python versions with pyenv local xxx .
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
Choose thin or unicorn (as indicated in the supervisor):gem install thin
echo 'gem "thin"' >> Gemfile
gem install unicorn
echo 'gem "unicorn"' >> Gemfile
The first one went. It remains to distort the supervisor from the console ' supervisorctl restart redmine.test.site ', or through the web muzzle ... and the redmine is ready to work redmine.test.site :

RefineryCMS Installation
Everything is similar, taking into account the official leadership:
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
An invitation page to create an administrator is waiting, refinerycms.test.site/refinery :

Install DjangoCMS
cd ~/web/djangocms.test.site/public_html
pyenv local 3.4.3
pip install djangocms-installer
A dialogue will follow. Select “Languages” = “en, ru”, “Twitter Theme” = “yes”, “with examples” = “yes”. The rest is by default.
djangocms -p . project
At the end they will be asked to indicate the login password and mailing address.
python manage.py cms check # check cms
pip install gunicorn
And here she is djangocms.test.site :

QUOKKA installation
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
And here is the last beast quokka.test.site :

It is worth noting that, unlike RbEnv / RVM, in PyEnv you can create virtualenv. These things are not mutually exclusive.
I hope my guide on installing various web applications was interesting.
Thanks.
In conclusion, the cat
