Previously, we setup a Arch Linux 512mb of Ram Rackspace Cloudserver, got some of the basics sorted out. Now that we have the server setup, lets jump right in and get rvm and Nginx rolling.
To get started on this we will install the dev tools we need to retrieve and compile some of the tools we need.
sudo pacman -Sy gcc make patch git
sudo pacman -Sy git
Create our deploy user, which will be an intermediate account that controls the web server, has the deployment rvm installation, can checkout the app, and has permission to checkout our app from version control. (Next Article, deployment).
sudo adduser Nginx
when prompted for additional groups add wheel, this is a nice quick shortcut to add a user on user creation to a specific group. If you forgot to, you can always retroactively manually edit the /etc/group file.
Now that we have the Nginx account, lets switch accounts to the Nginx account. And start setting up our rails specific stack. Using su, we can run a shell with substitute user and group ID, essentially allowing us perform fast user switching.
su Nginx
now we will jump to the Nginx users home directory
cd ~
Now as the Nginx, user we will essentially setup a remote environment very similar to the local development environment discussed in the past article(link), but with some key differences.
Lets install rvm, with the following command, and then following the on-screen instructions
bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
Re-hash utility locations library, this should allow us to access to the new utility without having to start a new session
hash -r
Test rvm, this should display the rvm usage.
rvm
If testing rvm failed, quickly start a new session, and rvm should be kicking.
exit
su Nginx
with rvm installed we can easily install same exact same version and patch level Ruby as our local development environment
rvm install ree
Just for consistency, set ree as the default ruby
rvm use ree --default
The easy and robust deployment of ruby on rails applications on apache and Nginx web servers brought to us by the Phusion guys.
In-order to ensure passenger and rvm play nicely, we will let rvm know which ruby we want to use for passenger. The bellow call will generate wrapper scripts in RVMs bin directory (see Notes below). These wrapper scripts ensure environment variables such as GEM_HOME and GEM_PATH are set correctly for applications run by passenger.
rvm ree --passenger
gem install passenger
The web server we will use is Nginx, it may not be known by all, but has proven incredibly stable, fast, and most importantly predictable. Current Nginx serves roughly 7% of the worlds domains, including some high profile domains including: WordPress.com and Hulu.com. Compared to its counter part apache, Nginx has a very low, and predictable memory footprint, which scales linearly with the number of concurrent requests, rather then apaches exponentially growing memory footprint. What this means for us, is that Nginx will perform faster, use significantly less memory, and stay out of the way.
sudo passenger-install-Nginx-module
to keep it simple, we will let the passenger gem compile and setup Nginx for us. In some situations one may need to compile custom modules into Nginx, but for us this should be fine.
when prompted choose 1 (Yes: Download and install Nginx for me)
Testing Nginx, lets start by running Nginx.
sudo /opt/Nginx/sbin/Nginx
By default Nginx should be serving from port 80, the default http port, so lets navigate over to your new appservers IP address in the browser. The resulting page should read.
Welcome to Nginx!
Lets just kill Nginx for now
sudo killall -9 Nginx
After this is done, we will need to tweek some of Nginx settings.
Lets get Nginx, setup as an arch daemon. The scripts that control specific daemon actions, such as start|stop|restart are located in.
/etc/rd.d/*
As we want Nginx to start as a daemon on boot, it is a good idea to have it conform to this standard.
First off all we will need to have access to the Nginx process id, lets open up the Nginx conf file, and simple uncomment the line in question. This will have Nginx drop its pid to file, so we can get access to it from our rc.d script
sudo vim /opt/Nginx/conf/Nginx.conf
or
sudo nano /opt/Nginx/conf/Nginx.conf
Uncomment
#pid logs/Nginx.pid;
Next lets drop in the appropriate daemon script for Nginx. I have provided one that should do the trick over at:
https://gist.github.com/fe07eaac258c57022851
To drop use this simply
sudo wget https://gist.github.com/raw/fe07eaac258c57022851/be31621ff47da247134606230c209bb1aba3c472/Nginx /etc/rc.d/Nginx
Lets set the executable bit
sudo chmod +x /etc/rc.d/Nginx
Now we can start and stop Nginx to our hearts content
sudo /etc/rc.d/Nginx start
sudo /etc/rc.d/Nginx stop
Now that we can make Nginx start and stop, it is a good idea to have Nginx start on boot, just in case our server has to be restart this should be automatic. This configuration is done from following file.
/etc/rc.conf
open the file in your favorite text editor.
sudo vim /etc/rc.conf
or
sudo nano /etc/rc.conf
or
...
look for the daemon section, which in my case was at the very bottom
DAEMONS=(syslog-ng network netfs crond)
and simple add Nginx to the list. Arch automatically looks in the /etc/rc.d/* folder for matching scripts and calls start on them. Scripts are loaded in the order that they appear in the daemons section of the rc.conf file.
DAEMONS=(syslog-ng network netfs crond Nginx)
To take full advantage of rvm we should point to passenger the specially wrapped rvm binaries. To do so we will edit the Nginx configuration file.
sudo vim /opt/Nginx/conf/Nginx.con
or
sudo nano /opt/Nginx/conf/Nginx.con
Find this line
passenger_ruby /home/Nginx/.rvm/rubies/ree-1.8.7-2010.02/bin/ruby;
and replace it with with
passenger_ruby /home/Nginx/.rvm/bin/passenger_ruby;
Now that we have the server more or less setup, Nginx running, passenger and Nginx playing nicely, and rvm powering the ruby stack. Its time for us to test it all out, and make sure we can boot a simple rails application.
Nginx
For testing purposes we will just have the Nginx default host point to where our test rails application will bes public directory, and then enable passenger. This is nice and simple, and will helps us debug if their are any problems.
To set the default host, open up the Nginx.conf in your favorite edit
sudo vim /opt/Nginx/Nginx.conf
or
sudo vim /opt/Nginx/Nginx.conf
Now look for the first server block, replace the existing root directive with
/srv/rack/example/public;
next, we will enable passenger for this block by simply adding the following line anywhere in the block:
passenger_enabled on;
finally your initial server block should contain
server {
...
root /srv/rack/example/public;
passenger_enabled on;
...
}
Now lets start or restart our Nginx processing to make sure everything is loaded correctly
sudo /etc/rc.d/Nginx restart
Now finally its time to test out your new stack with an example Rails application. First we will need to setup some simple directories that conform to those which we choose to specify in the Nginx.conf, and set the correct permissions.
sudo mkdir -p /srv/rack/
sudo chown Nginx /srv/rack
Now we can jump into the directory, install rails, and generate a nice fresh new rails application.
cd /srv/rack
Since we do not yet have rails installed we will need to do so in-order to generate the empty rails applications. Since this is a server install, we really dont need to install the rails documentation, so the --no-ri and --no-rdoc are appended to the gem install. This should speed the install up
gem install rails --no-ri --no-rdoc
rails example
Now that we generated rails, we will need to use bundler to install its dependencies, so Nginx can serve it.
cd exmaple
bundle install
And ... a full simple rails stack should be running. To verify this, surf over to your web servers IP address in your browser. You should see classy Welcome aboard rails fresh rails app start page.
By default rails uses sqlite3, but for most production cases this will not do the trick. One of the DBMS rails supports out of the box is mysql, so lets quick install and configure mysql.
sudo pacman -Sy mysql
sudo /etc/rc.d/mysqld start
/usr/bin/mysql_secure_installation
Follow the on-screen instructions, set the root password, and answer yes to the rest of the questions. You can always come back to this later on.
More then likely, we will want Mysql to start at boot, if that is the case simple add mysqld to daemons list at /etc/rc.conf
sudo vim /etc/rc.conf
or
sudo nano /etc/rc.conf
Find the line that looks like
DAEMONS=(syslog-ng network netfs crond nginx)
And Simply add mysqld to that list, the result should look like
DAEMONS=(syslog-ng network netfs crond mysqld nginx)