Running the Purpose Platform on Ubuntu Server 12.04 LTS - PurposeOpen/Platform GitHub Wiki

The configuration details provided here are to get Purpose Platform running on a production environment. These steps where used to setup a production environment running on Linode with: 2 web servers, a load balancer and 1 database server.

Web server installation

Like any other Rails application, the platform can be run on different web servers. We have tested using Nginx and Passenger. Below you will find the detail step to configure your Ubuntu web server from scratch.

Create user

  • adduser platform -m -s /bin/bash
  • passwd platform
  • Log out and log in with platform user

Install git

  • sudo apt-get install git

Install RVM

  • sudo apt-get update
  • sudo apt-get install build-essential
  • curl -L https://get.rvm.io | bash -s stable --ruby

Clone Platform repository:

  • mkdir -p /var/www && git clone https://github.com/PurposeOpen/Platform.git -b vps /var/www/platform

Install libs and gems:

  • sudo apt-get install libmysql-ruby libmysqlclient-dev libcurl4-openssl-dev
  • cd /var/www/platform && bundle install

Install Nginx & Passenger (for details on RVM integration see http://blog.phusion.nl/2010/09/21/phusion-passenger-running-multiple-ruby-versions/ and https://rvm.io/integration/passenger)

  • rvm use 1.9.3-p194
  • gem install passenger --pre --version 3.9.2.beta
  • rvmsudo passenger-install-nginx-module
  • wget -O init-deb.sh http://library.linode.com/assets/660-init-deb.sh
  • sudo mv init-deb.sh /etc/init.d/nginx
  • sudo chmod +x /etc/init.d/nginx
  • sudo /usr/sbin/update-rc.d -f nginx defaults

Deploy the application

  • sudo vim /opt/nginx/conf/nginx.conf

  • Update as follows:

      user platform;
      worker_processes  1;
    
      events {
          worker_connections  1024;
      }
    
      http {
          passenger_root /home/platform/.rvm/gems/ruby-1.9.3-p194/gems/passenger-3.9.2.beta;
          passenger_ruby /home/platform/.rvm/wrappers/ruby-1.9.3-p194/ruby;
    
          include       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"';
    
          sendfile        on;
    
          keepalive_timeout  65;
    
          server {
              listen       80;
              server_name  vps.platform.purpose.com;
    
              access_log  /var/www/platform/log/access.log main;
              error_log /var/www/platform/log/production.log info;
    
              passenger_enabled on;
              rails_env production;
    
              root /var/www/platform/public;
    
              error_page   500 502 503 504  /50x.html;
              location = /50x.html {
                  root   html;
              }
          }
    
          # HTTPS server
          #
          server {
              listen       443;
              server_name  vps.platform.purpose.com;
    
              access_log  /var/www/platform/log/access.log main;
              error_log /var/www/platform/log/production.log info;
    
              ssl                  on;
              ssl_certificate      /var/www/platform/certs/cacert.pem;
              ssl_certificate_key  /var/www/platform/certs/server.key;
    
              passenger_enabled on;
              rails_env production;
    
              root /var/www/platform/public;
          }
      }
    

To serve assets from server

  • bundle exec rake assets:precompile
  • Update config/environments/production.rb to: config.serve_static_assets = true

Cron jobs

The application has some jobs that take care of running background tasks. This jobs are run within a Linux cron. Below you can find the steps to configure the required crons.

  • Run crontab -e edit the crons that are started when the server is rebooted
  • Add the following entries:
    @reboot /var/www/platform/cron_runner.sh "clockwork lib/tasks/clock.rb" "/var/www/platform/log/clock.log"
    @reboot QUEUE=default /var/www/platform/cron_runner.sh "rake jobs:work" "/var/www/platform/log/worker.log"
    @reboot QUEUE=list_cutter_blaster /var/www/platform/cron_runner.sh "rake jobs:work" "/var/www/platform/log/list_cutter_blaster.log"

Database server installation

Despite the application has been developed using a database abstraction layer (ActiveRecord), it was only tested with MySql. In particular we are using MySql version 5.5. Below you find generic installation commands.

Install MySQL

  • sudo apt-get update && sudo apt-get upgrade
  • sudo apt-get install mysql-server mysql-client

Configure MySQL to be available for remote TCP connections

  • Edit /etc/mysql/my.cnf and comment out the bind_address setting
  • Execute the following queries:
    GRANT ALL ON *.* to root@'%' IDENTIFIED BY '<root password>';
    FLUSH PRIVILEGES;

Solr

This application uses Solr as search platform through the Sunspot gem.

When running on a production environment, the recommended strategy is setup a Solr instance on Java Container like Tomcat for example, that is what we have done. Our Solr instance is running on the database server.

To setup a Tomcat-based Solr instance you can follow these instructions: https://github.com/sunspot/sunspot/wiki/Configure-Solr-on-Ubuntu%2C-the-quickest-way

For Solr-Tomcat instance you will need to add a configuration file for Sunspot: config/sunspot.yml to tell your application where Solr is located (when working on development this file is not need because default settings are used).

Our Linode server is running Solr version 1.4.1.

Optional components installation

Memcached

  • Install:
    sudo apt-get install memcached
  • Allow remote connections:
    sudo vim /etc/memcached.conf
  • Update -l 127.0.0.1 to -l 0.0.0.0
  • Allow incoming connections through firewall:
    sudo iptables -A INPUT -p tcp --dport 11211 -j ACCEPT
  • Restart memcached:
    sudo /etc/init.d/memcached restart