Where developers come to connect, share, build and be inspired.

2

VPS Configuration from scratch - Rails, Nginx, PostgreSQL.

7369 views


enter image description here

Setting up a VPS can be a daunting task, especially if you're new and don't know how the bits and piece fit together.

Services like Heroku have tried to ease this burden by allowing people to focus on their code and not worry about their actual servers, but sometimes that added value comes with a steep price-tag. Other times Heroku just isn't a good fit. For example when you want to let your users upload files; Heroku doesn't have a persistent file system.

Today I'd like to show you the 'DevOps for Dummies' guide.

Please note that there are engineers out there who make a living fine tuning and monitoring servers.

While this guide will get you up and running for the foreseeable future, when your web application makes it big, you are probably going to need someone with knowledge in this particular field to really worry about these things.


Objectives:

Here's a small list of the things we're going to work on. Ideally, you want to follow this progression path when setting up a new box.

While there are tools out there like Chef, Puppet, etc; I want to do things manually so when the time comes for you to learn about these tools you notice the benefit they bring to the table.

  • What VPS should I use?
  • Initial Ubuntu Configuration
  • RVM installation
  • Ruby 1.9.3 installation
  • Rails 3.2.X installation
  • PostgreSQL installation
  • Passenger + Nginx installation

What VPS should I use?

There are many VPS offerings out there. Some inexpensive, some with more RAM, some with more Hard Drive space, ones with SSD drives, etc.

It's up to you to shop around online and find the one that fits your application needs best.

Two very solid offerings that I can vouch for are DigitalOcean and ASmallOrange. ASmallOrange is a bit more expensive but the upside is they are managed, meaning you'll have great support when things don't go the way you planned them.

Both have great support teams with amazing response times and excellent managements tools at your disposal.

In the end, shop around and pick one you like.

Try to pick one with at least:

  • 1GB RAM
  • 20GB Hard Drive capacity

Initial Ubuntu Configuration

When you purchase your VPS, I recommend using Ubuntu 12.10 x64.

One of the first things we want to do is disable root access to your server.

Let's start by creating a brand new user.

adduser your-user-name
# eg.: $ adduser sergiotapia

When you add the user, Ubuntu will prompt you for your full name, telephone, etc. You can safely just hit enter at each prompt for the default settings.

Now we need to allow this new user to install software as needed, but not as root.

sudo nano /etc/sudoers

Scroll down to the bottom of this file using your arrow keys, and add this line at the very end.

your-user-name ALL=(ALL) ALL
# eg.: sergiotapia ALL=(ALL) ALL

Press Ctrl + X to bring up the close dialog and type in Y to save your changes.

Now we need to disable ssh login to the root account. Remember: After this initial configuration your going to be using your newly created account to login.

Let's open up the ssh configuration file:

nano /etc/ssh/sshd_config

Look for a line that says PermitRootLogin. Change the setting from yes to no.

Press Ctrl + X to bring up the close dialog and type in Y to save your changes.

Restart the ssh server to have these changes take effect.

/etc/init.d/ssh restart

Finally, log out from your root account.

logout

Now that we are logged out, lets login using our new user credentials. Open up a terminal and login:

ssh your-user-name@your-ip-address
# eg.: ssh sergiotapia@192.168.1.1

Now that we have secured our server, let's update the software on Ubuntu.

sudo apt-get update
sudo apt-get upgrade

Let's install Git next; we need it to install a plethora of other software including RVM and Ruby.

sudo apt-get install git-core

RVM installation

Next let's install RVM. RVM will allow us to easily install any version of Ruby we want, and even upgrade versions when a new one comes out.

curl -L get.rvm.io | bash -s stable

Run a simple source command after RVM installs, so we can invoke it from the terminal.

source ~/.rvm/scripts/rvm

Try running this command to see if RVM installed properly. You should see a small notice telling you what version of RVM you're using.

rvm -v

Next comes the big-kahuna. We're going to install a lot of software! I won't go over them 1 by 1, Google what each package does if you are interested.

sudo apt-get install build-essential bison openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev

Ruby 1.9.3 installation

RVM is a fantastic! Here's how simple it is to install Ruby on your machine.

rvm install 1.9.3

This might take a while, or at least longer than the previous commands, so just let it run.

One it finishes let's make sure RVM uses this Ruby version as the default Ruby version, server-wide.

rvm --default use 1.9.3

Rails installation

Now we need to install Rails. You can run this command from anywhere on your server, you don't need to be inside any particular folder.

gem install rails

Run these two commands to see if everything went smoothly. You should see the versions printed nicely in your terminal.

ruby -v
rails -v

PostgreSQL installation

Ubuntu 12.10 has a very nice package that makes installing PostgreSQL a simple command away.

sudo apt-get install postgresql-9.1

Let's go ahead and change the password for Postgresql.

sudo -u postgres psql template1
ALTER USER postgres with encrypted password 'your_password';

Press Ctrl + D to leave the Postgresql prompt.

Next we need to enable connections to the Postgres server. Without this step, our Rails applications would not be able to connect. Open the default configuration file:

sudo nano /etc/postgresql/9.1/main/postgresql.conf

Find this line and uncomment it by removing the hash symbol in the beginning:

# Change this:
#listen_addresses = 'localhost'

# To this:
listen_address = 'localhost'

Finally, restart your Postgres server:

sudo service postgresql restart

Passenger + Nginx installation

We need to install a web server to allow visitors to actually see something in their browsers. I use Passenger with Nginx because I like the simplicity of the configuration files Nginx uses. (They look like simple JSON files.)

Passenger works just as well with Apache if that's what you prefer.

Let's install the Passenger gem first:

gem install passenger

Then install the Nginx module. The upside of this approach is that Passenger will automatically download, build and configure Nginx for usage. Sweet deal!

rvmsudo passenger-install-nginx-module

We're using the rvmsudo command instead of sudo because our system is using RVM.

The module will prompt you with two choices. Make sure you choose option 1.

More than likely it will fail to install, and tell you about some missing dependancies. Just run the commands it tells you to run to install the missing software.

At this point Nginx is install and configured on your machine. But we're going to configure one more thing to make it easy to stop and start your web server.

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

You should be able to stop and start your Nginx server easily with the following commands:

sudo /etc/init.d/nginx stop
sudo /etc/init.d/nginx start

And we're done! You've gone from ground-zero to an actual fully fledged server with all the things you need to host your Ruby on Rails applications.

If you visit your IP address you should see a familiar Nginx welcome page.

enter image description here

Pat yourself on the back kid, you've earned it!

enter image description here

In my next article, I'm going to show you how to configure Nginx to host N-amount of Ruby on Rails applications. Stay tuned or follow me on Twitter to be notified when I publish it: @lostinthegc

Comments

  • Avatar_joost

    Actually since this week you can install Passenger/nginx using official packages. No need to use the gem any more. This has the advantage that nginx will be started on boot and everything is kept up to date automatically. See http://blog.phusion.nl/2013/09/11/debian-and-ubuntu-packages-for-phusion-passenger/

  • 2af4ea9bb6380b59d05d2b9b6d8112e9

    My install keeps freezing when I do the rvmsudo passenger-install-nginx-module can you help?

  • Photo_on_2012-07-30_at_18.13

    @pixel67: Unfortunately, I can't. I've followed my own guide yesterday when setting up another VPS and everything works perfectly. Do you get an error message when installing or does it just freeze?

  • User-avatar

    Hi, I get a 404 error when I try hitting my server at http://localhost:3000/lookup_all/songs.json for data. Before when I used webrick, I used to get a json resposne with data from my Postgres DB but now I get this 2013/09/03 23:54:25 [error] 24750#0: *1 open() "/opt/nginx/html/lookupall/deities.json" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET /lookupall/deities.json HTTP/1.1", host: "localhost:3000"

    How can I configure nginx to return the app data ?

  • Photo_on_2012-07-30_at_18.13

    @haripoter77: That's an issue either an issue with your route or your action.

    Make sure you have a route set up for that action controller.

    Also make sure that action is returning JSON.

    render json: @deities
    
  • User-avatar

    You mean in config/routes.rb ? Yes, I already have it. Also as I mentioned earlier, it was rendering a JSON response when I was running with the Webrick server

    render :json => {"nameslist" => nameslist}.to_json

    Or are you saying nginx has a different routing mechanism other than the app's routes.rb ?

    Thanks

  • Eb23d1f83f17afd61a9a49999a3b603d

    @haripoter77

    I assume your trying to curl from a SSH session on the VPS, otherwise, going to localhost:3000 from a browser will try to go to your local machine. That should be clear as to why that won't work. Your gonna wanna try to use the IP of the VPS.

    Also nginx, by default, binds to port 80 so trying to use port 3000 will also not work.

  • Photo_on_2012-07-30_at_18.13

    @tilsammans: That is great news! I didn't know that; thanks for sharing!

Add a comment