3. Setup the Web Server Manually

Now we have a fully working, modern ruby setup. We just don’t have a web server, rails or a database up. Let’s remedy the first two by using passenger.

Passenger is an application server. You need to use it to allow Nginx to communicate with the Rails app (like mod_php). Otherwise you would need to use the almost obselete cgi (Common Gateway Interface implemented in Nginx) to communicate. For this book I chose Passenger because it’s easier for newcomers to understand and get started. Unicorn is an alternate application server that offers 100% uptime. However there are drawbacks. Unicorn takes alot more memory and it can only host one Rails app per instance. Stick with Passenger for now to get confortable and you can switch to Unicorn in the future.

Install passenger with our newly setup rubygems

gem install passenger --no-ri --no-rdoc

Now this is the fun part. With RVM and passenger you can automate the installation and (most of the) configuration of nginx.

rvmsudo passenger-install-nginx-module

Too bad it fails on stock Ubuntu 12.04. It will tell you to use 3 different terminal commands to install the necessary packages. I have condensed them for your convenience.

sudo apt-get install build-essential libcurl4-openssl-dev zlib1g-dev -y

rvmsudo passenger-install-nginx-module

Choose option 1. Hit enter for the default directory.

Now start nginx because it will not start on its own.

sudo service nginx start

Now it will give another error. Passenger nginx doesn’t come with the nice Debian/Ubuntu scripts. Let’s remedy that.

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

Now any of these 3 commands will work. Use nginx start.

sudo /etc/init.d/nginx stop

sudo /etc/init.d/nginx start

sudo /etc/init.d/nginx restart

Type your remote vps’s ip address into the broswer url to see your new server’s index page.

You now have a functioning webserver. You now just need to configure it and upload your rails app.

Let’s open the nginx configration.

sudo nano /opt/nginx/conf/nginx.conf

There should be a server bracket. Change the text inside to this.

server { 
  listen 80; 
  server_name example.com; 
  passenger_enabled on; 
  root /var/www/your_rails_app/public; 
}

Nginx should now give you an error when you visit your ip address.

Nginx also gives it’s version number which is really bad. An attacker could look up exploits for your version of nginx with this info. Let’s fix that.

Before the server add this line like so.

server_tokens off;
server { 
  listen 80; 
  server_name example.com; 
  passenger_enabled on; 
  root /var/www/your_rails_app/public; 
}

Restart the server

sudo /etc/init.d/nginx restart

Check again to see the version number was removed.

Now let’s finally get passenger and your rails app working.

You need to install a web server within rails to run the app.

sudo apt-get install nodejs

Create the directory.

sudo mkdir /var/www

Now for laughs and giggles create a new rails app on the vps.

rails new your_rails_app

Add some scaffolding.

rails g scaffold sales

Copy it over to /var/www

cp -r your_rails_app /var/www/

Go to your server’s public page to see your app in production (it won’t work yet, but we will get to that).

But what if you want to copy over your own local version to the vps? Like a real developer? We use rsync to accomplish that.

Rsync is a tool intended to automate file uploading. It’s used all the time in backups and other server admin tasks. Let’s use it to upload the local rails project.

Make sure to exit the vps’s ssh.

Now rsync your app to the vps.

rsync -avz -e ssh your_rails_app user@148.211.114.67:/var/www/

sudo chmod -R 755 your_rails_app

sudo chown -R 755 your_rails_app

sudo chown -R user your_rails_app

Now ssh back into the vps and cd into /var/www

cd your_rails_app

Run the bundler.

bundle install

Try visiting a dynamic part of your website (or /sales of the one created). You should get an error. But what could it be? You can check log/production.log in your rails app to find out.

If you get a table error make sure you didn’t forget to migrate the db (for production):

rake db:migrate RAILS_ENV="production"

If you see an assets error you need to run a command to compile them.

rake assets:precompile

If you’re wondering, yes, you need to rerun the assets command everytime you upload a new version (specifically whenever you change javascript, css or other assets). Thankfully, we can automate this as told in the automation chapter.

Your website should be working by now.