Server configuration
Configuring a local virtual machine with Virtualbox and Vagrant is easy and out of the scope of this post, but it could help taking a look at the following links:
After you ensured ruby 2.0.0 is installed, you can install uWSGI via rubygems:
gem install uwsgi
Clone the Feedbin repo into your machine, I cloned the repo into ~/apps:
git clone https://github.com/feedbin/feedbin.git
and comment out unicorn, capistrano-unicorn, therubyracer and foreman in the Gemfile:
# gem 'capistrano-unicorn', github: 'sosedoff/capistrano-unicorn', ref: '52376ad', require: false
# gem 'unicorn'
# gem "therubyracer", require: 'v8'
# gem 'foreman'
Feedbin takes advantage of env variables, so we add dotenv-rails to the Gemfile, this way we don’t have to export the env settings each time we run a command in console:
gem 'dotenv-rails'
dotnev-rails reads settings from the .env file:
BUNDLE_GEMFILE=/home/vagrant/apps/feedbin/Gemfile
RAILS_ENV=production
MEMCACHED_HOSTS=127.0.0.1:11121
POSTGRES_USERNAME=vagrant
DATABASE_URL=postgres://vagrant:secret@127.0.0.1:5432/feedbin_production
SECRET_KEY_BASE=yoursecretkey
And now, bundle:
bundle install --without development test
Let’s create a new database:
createdb -T template0 feedbin_production
go ahead loading schema and running the migrations (we need to load the schema because at the moment there is an error in one of the old migrations preventing the rake task to be completed correctly)
rake db:schema:load
rake db:migrate
Application setup is completed. Now we can configure uWSGI.
uWSGI
Create the uwsgi config file in config/uwsgi.ini:
[uwsgi]
# this is the application user/uid to use in our uWSGI process. uid = vagrant
# Setting master = true I'm telling uWSGI to enable the master process.
# This way uWSGI can act as an application instance monitor master = true
# Number of application instances to spawn processes = 2
# Full path of the unix socket that apache/nginx will use to speak to uWSGI socket = /home/vagrant/apps/feedbin/tmp/uwsgi.sock
# Setting this modifier to 7 will enable the ruby/rack plugin socket-modifier1 = 7
# Application root directory chdir = /home/vagrant/apps/feedbin
# Rackup file location rack = /home/vagrant/apps/feedbin/config.ru
# post-buffering and buffer-size are required by the Rack specification post-buffering = 4096buffer-size = 25000
# load the bundle subsystemrbrequire = rubygems
rbrequire = bundler/setup
# disable logging
disable-logging = true
# uWSGI log file location
daemonize = /home/vagrant/apps/feedbin/log/uwsgi.log
# uWSGI pid file location
pidfile = /home/vagrant/apps/feedbin/tmp/uwsgi.pid
# Start sidekiq when you start the application.
# Using smart-attach-daemon uWSGI can be used to start external services,
# and monitor them (for example it automatically restarts the daemon when you restart uWSGI)
smart-attach-daemon = %(chdir)/tmp/pids/sidekiq.pid bundle exec sidekiq -P %(chdir)/tmp/pids/sidekiq.pid -e production
As you can see we configured only one file to start both the application itself and Sidekiq.
Now we can start the application with the follow command:
uwsgi ~/apps/feedbin/config/uwsgi.ini
Our Feedbin instance is now up and running, but in order to let it work properly we need to configure nginx/apache in front of it. If you need to install nginx you can follow the instructions at this Ubuntu community link.
Let’s now create the application configuration; below there is my nginx config file (we also need to create https self-signed certs for Feedbin):
server {
listen 80;
listen 443 default ssl;
ssl_certificate /etc/nginx/certs/myfeedbin.crt;
ssl_certificate_key /etc/nginx/certs/myfeedbin.key;
location / {
root /home/vagrant/apps/feedbin/public;
include uwsgi_params;
if (!-f $request_filename) {
uwsgi_pass unix:///home/vagrant/apps/feedbin/tmp/uwsgi.sock;
}
uwsgi_param UWSGI_SCHEME $scheme;
uwsgi_param SERVER_SOFTWARE nginx/$nginx_version;
uwsgi_param HTTPS on;
uwsgi_modifier1 7;
location ~ ^/assets/ {
expires 1y;
add_header Cache-Control public;
add_header ETag "";
break;
}
}
}
Restart nginx.
DONE!
Open your browser and enjoy: the application is up and running!
Appendix: Other useful uWSGI settings
RVM
If your app uses rvm you can add the following to the uwsgi.ini in order to load the rvm environment:
# load rvm
rvm-path = /home/vagrant/.rvm
Environment Variables
We used dotenv to set environment vars inside a config file, but you may prefer to set these variables directly inside uWSGI. You can do that (for our example) by adding the following to uWSGI.ini
env = BUNDLE_GEMFILE=/home/vagrant/apps/feedbin/Gemfile
env = RAILS_ENV=production
env = MEMCACHED_HOSTS=127.0.0.1:11121
env = POSTGRES_USERNAME=vagrant
env = DATABASE_URL=postgres://vagrant:secret@127.0.0.1:5432/feedbin_production
env = SECRET_KEY_BASE=yoursecretkey
The pattern is env = <name>=<value>
Final considerations
uWSGI is a powerful piece of software with a lot of interesting features like fast-routing, auto scaling, support for new plugins, alarms, mules, crontab, application caching and multiple applications management mode… oddly enough it’s so much more famous in the python world than in the ruby community.
Leave a Reply