Installing a Ruby on Rails app (Helpy) on CentOS 7.3 with Unicorn, Hiawatha and PostgreSQL
For practice, I went ahead and setup a Ruby on Rails app - Helpy - on CentOS 7.3. This is how I did it:
1. Get a more modern Ruby:
CentOS 7 comes with 2.0.0p648 which is kinda old by now. Download a more modern RPM from here: https://github.com/feedforce/ruby-rpm/releases
yum -y install https://github.com/feedforce/ruby-rpm/releases/download/2.4.1/ruby-2.4.1-1.el7.centos.x86_64.rpm
2. Install gcc, gcc-c++, some development libraries and git
yum -y install git ruby gcc gcc-c++ zlib-devel libxml2-devel patch sqlite-devel ImageMagick-devel
3. Install the Postgres repo:
yum -y install https://download.postgresql.org/pub/repos/yum/9.3/redhat/rhel-7-x86_64/pgdg-redhat93-9.3-2.noarch.rpm
4. Install Postgres:
yum -y install postgresql93-server postgresql93-devel
5. Initialize the Postgres server:
sudo -u postgres /usr/pgsql-9.3/bin/pg_ctl initdb --pgdata=/var/lib/pgsql/9.3/data/
6. Start the server and while you're on it make the database start on boot:
systemctl start postgresql-9.3
systemctl enable postgresql-9.3
7. Get the latest stable Helpy release, untar it and move it under /opt/helpy:
cd /tmp
curl -LO https://github.com/helpyio/helpy/archive/1.2.1.tar.gz
tar -xzf 1.2.1.tar.gz
mv helpy-1.2.1 /opt/helpy
8. Install the bundler gem:
gem install bundler --no-ri --no-rdoc
9. In your Gemfile (/opt/helpy/Gemfile) add this line at the bottom of the file:
gem "therubyracer"
10. Get all dependency gems:
ln -s /usr/pgsql-9.3/bin/pg_config /usr/bin/
cd /opt/helpy
bundle install --without development test
11. Add a “root” user to postgres and create a “helpy_production” database owned by the “root” user:
sudo -u postgres createuser -d root
sudo -u postgres createdb -O root helpy_production
12. Edit the file /opt/helpy/config/database.yml and comment out the lines:
username: helpy
password: <%= ENV['helpy_DATABASE_PASSWORD'] %>
When done they should look like this:
# username: helpy
# password: <%= ENV['helpy_DATABASE_PASSWORD'] %>
13. Apply the provided migrations:
RAILS_ENV=production bundle exec rake db:create
RAILS_ENV=production bundle exec rake db:migrate
RAILS_ENV=production bundle exec rake db:seed
14. Compile your assets locally: (this might take around five minutes)
RAILS_ENV=production bundle exec rake assets:precompile
15. Set a random key that’s used by /opt/helpy/config/secrets.yml - needs to be at least 32 characters long.
export SECRET_KEY_BASE=`openssl rand -hex 48`
16. Test the app using Unicorn:
RAILS_ENV=production unicorn -c config/unicorn.rb
17. You should now be able to check out Helpy on http://$YOUR_IP:8080/
This is what it looks like in my case:
18. Try to login:
You can try to login by clicking the 'Sign in' link on the top right, using username: admin@test.com and password: 12345678
19. Install the Anku Linux repository to get Hiawatha:
yum -y install http://anku.ecualinux.com/7/x86_64/anku-release-8-1.noarch.rpm
20. Get Hiawatha (and the net-tools package so we can get the netstat command):
yum -y install hiawatha net-tools
21. Edit the Hiawatha configuration to proxy requests to Unicorn:
Edit the /etc/hiawatha/hiawatha.conf and add this configuration at the bottom of the file - don't forget to replace "$replace_with_your_external_ip" with your external IP so that you can visit the website!
VirtualHost {
Hostname = $replace_with_your_external_ip
WebsiteRoot = /opt/helpy/public
AccessLogfile = /var/log/help-access.log
ErrorLogfile = /var/log/helpy-error.log
ReverseProxy !^/(assets|images|javascripts|stylesheets|system)/ http://127.0.0.1:8080/
}
22. Restart hiawatha - you’re done :)
systemctl restart hiawatha.service
23. Install Siege to run a quick benchmark:
yum -y install epel-release
yum -y install siege
23. Run a quick benchmark using Siege for an image with and without Hiawatha:
First hit Unicorn directly - this is a simple .PNG file - we'll use this command - note the port 8080 for Unicorn:
siege -b -c 3 -t 10s http://45.58.43.247:8080/assets/logo-f63b1eddb33664833b4a5677abd5f482a2ee64d344bf22e6fb7566664541a399.png
Here's what the switches mean:
-b = run in benchmark mode - no delay between requests
-c = 3 concurrent number of users to simulate - we'll use 3
-t 10s = run for 10 seconds and then stop
Here's the results when hitting Unicorn:
Lifting the server siege...
Transactions: 5021 hits
Availability: 100.00 %
Elapsed time: 9.22 secs
Data transferred: 19.11 MB
Response time: 0.01 secs
Transaction rate: 544.58 trans/sec
Throughput: 2.07 MB/sec
Concurrency: 2.96
Successful transactions: 5021
Failed transactions: 0
Longest transaction: 0.08
Shortest transaction: 0.00
Here's the Siege command for Hiawatha - note the port 80 for Hiawatha:
siege -b -c 3 -t 10s http://45.58.43.247:80/assets/logo-f63b1eddb33664833b4a5677abd5f482a2ee64d344bf22e6fb7566664541a399.png
And here's the results:
Lifting the server siege...
Transactions: 37660 hits
Availability: 100.00 %
Elapsed time: 9.72 secs
Data transferred: 143.30 MB
Response time: 0.00 secs
Transaction rate: 3874.49 trans/sec
Throughput: 14.74 MB/sec
Concurrency: 2.72
Successful transactions: 37660
Failed transactions: 0
Longest transaction: 0.01
Shortest transaction: 0.00
Yep your eyes don't deceive you. 37660 vs 5021 transactions - a 650% increase.
Sources:
- Stack Overflow - authentication - PostgreSQL error: Fatal: role username does not exist
- (think) - Ruby Tip #2: Get a List of All Rake Tasks
- Super User - User permissions for creating PostgreSQL DB
- Stack Overflow - Rails App Not Serving Assets in Production Environment
- Helpy Support - Installing Helpy using the Digital Ocean Rails Image
- Sinatra Recipes - Deployment - Nginx Proxied To Unicorn
- The Remarkable Labs Blog - Benchmarking and Load Testing with Siege