Ubuntu 8.04 Rails Server Using Passenger - Part 2 26

Posted by Ron Valente Tue, 13 May 2008 17:46:00 GMT

Introduction

Here is the, the long awaited second part of my extensive guide on setting up a rails server running on Ubuntu 8.04. Everything should be going smoothly so far and you should be at the point where we need to setup Apache and link everything together. This guide will be quite verbose and much longer than the first one. This is due mostly to all the configuration that will be required. That being said I will contemplate making a third part of this guide that will cover the version control and capistrano recipes. Your thoughts are greatly apreciated, esecially if you want me to cover any other features or topics after you finish reading this guide.

As pointed out by a reader, some people may not have read part 1 yet. Click here to read Part 1 of this guide.

Enabling GPM

Note: You are going to want to have GPM enabled for this if you are just using Ubuntu Server. GPM will allow you to copy and paste output from the terminal using your mouse.

sudo apt-get install gpm
sudo /etc/init.d/gpm start

Mod_Rails

To Start the installation of passenger after it has been installed via the gem run the following command:

sudo passenger-install-apache2-module

This will commence the user-friendly installer created by the Phusion team. My hats off to Phusion for making something so incredible sexy.

Run the following command in a new terminal (Alt-F2):

sudo vim /etc/apache2/apache2.conf

Scroll down the page the bottom of the configuration file and right about the "# Include of directories ignores editors" add the following from the output of the passenger install screen. Copy YOUR output NOT mine.

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-1.0.5/ext/apache2/mod_passenger.so
RailsSpawnServer /usr/lib/ruby/gems/1.8/passenger-1.0.5/bin/passenger-spawn-server
RailsRuby /usr/bin/ruby1.8

NameVirtualHost *:80

Now that you are done with the passenger install we need to take our rails app and create a virtual host for this app. To do that run the following command.

sudo vim /etc/apache2/sites-available/test

Once the file is open for editing add the following but change the parts specific to your application.

Note: The ServerName MUST be resolvable and resolve to the host that the application is running on.

<VirtualHost *:80>
    ServerName test.demo.rails
    DocumentRoot /var/rails/test/public
</VirtualHost>

Now that the virtual host is created and we dont need the default page anymore we can enable the test app vhost and disable the default vhost.

sudo a2dissite default
sudo a2ensite test

Creating Test Application

First things first we want to make the directory that all the rails apps we will be using will be stored.

sudo mkdir -p /var/rails
cd /var/rails

Now we want to create the rails skeleton and hand the permissions over to the apache web server.

sudo rails test
sudo chown -R www-data:www-data test

Once this is complete we are now ready to start the customization of the application and setting up the databases.

Setting Up MySQL

We want to login to the mysql database using the root account and the password we set earlier.

sudo mysql -p
--Enter Password--

There are many parts of MySQL which I do not like, like their user management. It is a poor way to manage access to the database. That being said it still is one of the more popular databases and it has a smaller memory footprint than PostgreSQL.

Creating the Databases

mysql> CREATE DATABASE test_development;
mysql> CREATE DATABASE test_test;
mysql> CREATE DATABASE test;

Creating a User and Setting the Password for the test database

The code listed below will add a user called "testapp" with the password "testpass", I recommend that you make your passwords extremely complex. For example a 16 character password would work wonderfully because it is stored in the database.yml so you dont need to memorize it.

mysql> GRANT all privileges ON test_development.* to testapp@"localhost" IDENTIFIED by 'testpass';
mysql> GRANT all privileges ON test_test.* to testapp@"localhost" IDENTIFIED by 'testpass';
mysql> GRANT all privileges ON test.* to testapp@"localhost" IDENTIFIED by 'testpass';

This command below will flush the privileges so that the access levels we just added will take effect.

mysql> FLUSH PRIVILEGES;

Configuring Rails App To Connect To the Database

Now that the database is configured properly we need to tell the rails app we created about the database. This is all done in the database.yml file.

cd /var/rails/test/config
sudo vim database.yml

Now that we are editing the database.yml file, you want to make you file look as follows...

login: &login
  adapter: mysql
  username: testapp
  password: testpass
  socket: /var/run/mysqld/mysqld.sock

development:
  <<: *login
  database: test_development

test:
  <<: *login
  database: test_test

production:
  <<: *login
  database: test

Last Minute Tricks...

Passenger does not like the .htaccess file to be in the public directory of the rails app. To remove this file just run the following command.

sudo rm /var/rails/test/public/.htaccess

Testing the Test Application

Now we have setup passenger to point at our rails app and we have to just restart the webserver.

sudo /etc/init.d/apache2 restart

Edit the /etc/hosts file on your client computer if you do not have DNS setup and add the following line.

SERVER_IPADDRESS test.demo.rails

Now open a web browser and type in the URL specified in the hosts file.

You should see the default "Welcome to Rails" screen

Status Checklist

Should Be Completed

  • Installed All Packages/Gems
  • Installed Passenger
  • Setup Apache 2.2.8 to use Passenger
  • Created Test Rails App
  • Created Databases
  • Configure Test Rails App To Use MySQL Database
  • Test Rails App is Functioning

Left To Do

  • SSH Goodies
  • Reader Suggestions

SSH Goodies

This section pertains to ssh security and best practices. SSH is a very important service that is run on any server and must be configured properly in order to be secure. By the end of this section you should have a "more secure" server that can securely be accessed via your computer using RSA encrypted SSH keys instead of passwords.

Creating Keys on your Client

This is a very simple process, all you need to do is run one command.

ssh-keygen

Now that this is running you will want to accept the default location to save your keys and type a password when prompted. This will password protect your keys for added security. You output should look as follows.

Generating public/private rsa key pair.
Enter file in which to save the key (/home/rvalente/.ssh/id_rsa): 
Created directory '/home/rvalente/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/rvalente/.ssh/id_rsa.
Your public key has been saved in /home/rvalente/.ssh/id_rsa.pub.
The key fingerprint is:
60:8e:b1:4c:cd:df:4d:82:b2:c4:05:97:0b:1b:56:fd rvalente@ubuntu

Now all you need to do is copy this key from your client machine to you server as follows. Make sure you use the account on your server instead of the account I list below.

scp .ssh/id_rsa.pub SERVER_IPADDRESS:.ssh/authorized_keys

Once that process completes then turn off password authentication on your ssh server. You do that but opening your /etc/ssh/sshd_config and changing this line.

#PasswordAuthentication yes
PasswordAuthentication no

That is it, now your server will use keys for authentication only.

Last but Not Least

I will be writing a part three of this guide for the capistrano/git version control and automation of a rails server. Since there are not many complete guides and they stop before the actual system administration occurs. Before I do this part three I want reader input for anything that you would like to see on top of the capistrano recipes and version control topics. Any input is greatly appreciated.

Thanks for reading!

-Ron

Ubuntu 8.04 Rails Server Using Passenger 20

Posted by Ron Valente Wed, 07 May 2008 02:50:00 GMT

Introduction

So before my monstrous OpenSolaris 2008.05 post on setting up a Ruby on Rails server I decided to write a guide on setting up a Ubuntu 8.04 server guide for all you Slicehost users! I decided to write this guide because of the new optimized kernel that was added to Ubuntu Server 8.04 for virtualized environments. I also wanted a complete guide that would be a solid reference and now just have bits and pieces for upcoming sysadmins will get lost when reading.

For simplicity I will start with a black machine and build upon that. Use the comments section for specific questions or starting points. I will try to do my best at answering any and all questions.

Requirements

This section will go over the simple requirements of the entire setup.

Hardware

Ubuntu 8.04 Server - This could be anything below:

  • Slicehost
  • VMware
  • Bare Metal Install

Software

  • Apache 2.2.8
  • MySQL/PostgreSQL/SQLite3
  • Git
  • Ruby
  • Rubygems
    • Rails
    • Capistrano
    • RSpec
    • Ultrasphinx
    • Passenger

Installation of Software

First thing before we start installing anything on this machine we must update the server. This is very simple with Ubuntu, it is two simple commands and you are all set. You only need to reboot the machine if a kernel was installed.

sudo apt-get update
sudo apt-get dist-upgrade

Now that the machine is updated we must install some essential tools in order to build software on this server. Once we are done with the setup it would be a good idea to remove these tools to increase security on our server.

sudo apt-get install build-essential

Now we are all set with the preparation of the server and we can start installing the software we need to get going.

Web Server

For the web server I chose to use Apache 2 because of the new Passenger gem or (mod_rails). This gem is great because of the simplicity to deploy new applications.

sudo apt-get install apache2 apache2-dev

Database Server

The database server that should be used is completely up to your preference. My recommendation is PostgreSQL. PostgreSQL is a very robust and fast database server that is rock solid. It does use a lot of resources so for Slicehost it may not be the best choice. A major player for a slim and fast database for Slicehost should be SQLite3. It is a wonderful database and should be thrown out so quickly because of its lack of a client/server architecture.

For this tutorial I will install MySQL because of its popularity with the Rails community.

sudo apt-get install mysql-server

When prompted enter a root password, make this complex and write it down.

Version Control

Git is the most sexy version control system every created. I will never look back to subversion again. Now that capistraon and redmine both support git I have no reason to even thing about those awful three letters.

To install git is yet another apt-get command away. Run the following command in the terminal of your new server.

sudo apt-get install git-core curl gitweb

gitweb is an optional web frontend for your applications. I do not use it because I use GitNub a RubyCocoa application for the Mac.

Once that finishes git is completely installed and ready to go.

Ruby

Installing Ruby on Ubuntu 8.04 is quite simple. Just another apt-get and you are all set... almost. Since the inception of Ruby 1.9.0 distributions have been naming the current stable release of ruby "ruby1.8" That being said we will make a couple symlinks.

Ruby 1.8.6

To install all the tools you will want on this server run the following command:

sudo apt-get install ruby1.8 ruby1.8-dev rdoc1.8 ri1.8 libopenssl-ruby1.8

Rubygems

I refuse to install Rubygems with apt-get. This is such a terrible idea in my opinion. There is no reason to install rubygems with a package manager because it can update itself. I will go over how to update rubygems later in this howto.

wget http://rubyforge.org/frs/download.php/35283/rubygems-1.1.1.tgz
tar -xzf rubygems-1.1.1.tgz
cd rubygems-1.1.1
sudo ruby1.8 setup.rb

Optional: Once you are done with install just run the next three commands to make using gems and Rubygems just as before.

sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby
sudo ln -s /usr/bin/irb1.8 /usr/bin/irb

Recommended Gems

Here is a list of recommended gems that should be installed once rubygems is installed. At the very least you must install rails and passenger.

sudo gem install rails
sudo gem install capistrano
sudo gem install rspec
sudo gem install ultrasphinx
sudo gem install passenger
sudo gem install mysql

Part Two

Next week I will go over how to connect all the pieces together and get a sexy Ruby on Rails server running smoothly. I will go over configuring git on your local computer as well as setting up passenger and capistrano to function with all of the above sexy applications we just installed.

Backing Up Your Filesystem and PostgreSQL Database with Amazon S3 and Duplicity 2

Posted by Ben Allen Mon, 22 Oct 2007 02:21:00 GMT

Introduction.

Amazon offers a great data storage service called Amazon Simple Storage Service or Amazon S3. It is a low cost, highly available service that charges by the Gigabyte stored and transfered. There are a number of utilities that have integrated support for Amazon S3. Duplicity is one of them. It integrates support for Amazon S3, among other storage methods, with rdiff. In all, duplicity allows an effective way to do incremental encrypted backups.

Below you will find the steps to setup backing up to Amazon S3 with Dupliciy. Included is my own Perl script that can be used to run the backup unintended with Cron. The script also includes support to dump a PostgreSQL database before the backup commences, and then include it in the backup to S3. It also supports emailing any number of people with notifications of completed backups as well as any errors. Feel free to post in the comments any questions or bugs you find. Enjoy.

Steps

  • Install Duplicity
  • Create GPG Key
  • Sign up for Amazon S3
  • Example Perl Script for Backup

Install Duplicity

Requirements for Duplicity 0.4.3

  • Python v2.4 or later (see the Python homepage)
  • Librsync v0.9.6 or later (downloadable from the librsync download page)
  • GnuPG for encryption (see the GnuPG homepage).
  • GnuPGInterface 0.3.2 or later (Sourceforge Home)
  • Boto 0.9b or later (Boto Home)
  • pexpect 2.1 or later (Pexpect Home) or python-pexpect from your distro's repository.

Reference http://duplicity.nongnu.org

Install on Ubuntu

On Ubuntu you simply can use apt to install Ubuntu. All the above dependancies will be installed automatically.

apt-get install duplicity

Create GPG Key

Gnupg should already be installed as a dependance of Duplicity. To create a key run the following:

$ gpg --gen-key
gpg (GnuPG) 1.4.6; Copyright (C) 2006 Free Software Foundation, Inc.

The default type of key is fine here.

Please select what kind of key you want:
    (1) DSA and Elgamal (default)
    (2) DSA (sign only)
    (5) RSA (sign only)
Your selection? 1

The default keysize is more then sufficient.

DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048

For backup use, there's no real reason to have the key expire, so select 0 here.

Please specify how long the key should be valid.
    0 = key does not expire
    <n>  = key expires in n days
    <n>w = key expires in n weeks
    <n>m = key expires in n months
    <n>y = key expires in n years
Key is valid for? (0) 0

Enter your name, email address and a comment.

Real name: John Doe
Email address: jon@sysadminschronicles.com
Comment: Key for Duplicity

Confirm the key details and enter O for Okay.

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

Enter a phasehrase. Make sure you remember this as you will need it later on, as well as to unencrypt any files from a restore. In the example script $ENV{'PASSPHRASE'} is where you use this password.

Enter passphrase: password
Repeat passphrase: password

At the end of the key being generated GPG will print the key name, copy down the eight character name. In the example script $gpg_key is where you use this key name.

gpg: key F1A3D642 marked as ultimately trusted
public and secret key created and signed.

Your private and public key are now located in ~/.gnupg folder.

Copy this folder to the home directory of the user you want to run the backup as. For example its likely you are going to have to run the backup as root because of permissions on the files you plan to backup, so copy this folder to /root. Make sure root doesn't already have a GPG key used for other purposes.

sudo cp -R ~/.gnupg /root

You can delete the original .gnupg folder as there is no longer any use for it.

Note: You really need to backup your GPG key offsite. Meaning back it up somewhere other then Amazon S3 and the machine you are using the key on. If you loose your GPG key, your backup is useless, as you will not be able to unencrypted it.

Sign up for Amazon S3

Goto Amazon Web Services and sign up for an account. They will want a credit card for billing. Once you login, navigate to the Amazon Simple Storage Service page and sign up for the service. Now using the top right button labeled Your Web Services Account, click the AWS Access Identifiers link. Copy down your Access Key ID and Secret Access Key for use in the below script. $ENV{'AWS_ACCESS_KEY_ID'} and $ENV{'AWS_SECRET_ACCESS_KEY'} is where these two values are used in the example script.

Example Perl Script for Backup

Now that you have a GPG key created, Duplicity installed, and your AWS account created you can start a backup. The following is a Perl script I created to backup a set of specified directories as well as dump our entire PostgreSQL and back it up. If you don't need the PostgreSQL functionality delete or comment out the section that starts with the comment #Dump database.

Note: If you did as above and copied the GPG key to the root home folder, you will need to run this script as root. If you use sudo to gain root privileges make sure you use the - H flag to set the HOME environmental variable to root's. Otherwise either login as root or use su - to gain root privileges.

Requirements

  • MIME::Lite perl module
  • Duplicity
  • pg_dumpall
  • Amazon S3 Account
  • GPG key
  • SMTP server that can relay mail

backup_s3.pl

#!/usr/bin/perl

use strict;
use MIME::Lite;
my $subject;
my $backupOut;

#Where to backup the database too.
my $db_backup_dir = "/usr/local/backup/db_data";
#What to class the database backup file.
my $db_backup_filename = "dumpall.sql";

#What user to dump the database as.
my $db_user = "postgres";

#Path to pg_dumpall
my $pg_dumpall = "/usr/bin/pg_dumpall";

#Folders to be backed up.
my @backup_folders = ('/var/www', '/etc', "$db_backup_dir");

#Set force to 1 to actualy delete files found to be outdated or orphaned. 
my $force = 0;

#Check or delete files older then: (See duplicity's man page for acceptable values)
my $older_than = "2M";   

#Path to duplicity
my $duplicity = "/usr/bin/duplicity";

#What Amazon S3 Bucket to use.
my $s3_bucketname = "SetMe";

#What GPG key to use.
my $gpg_key = "SetMe";

#Your GPG passphrase
$ENV{'PASSPHRASE'} = 'SetMe';

#Where to send notification emails.
my @to_email = ('ben@domain.com', 'ron@domain.com');

#SMTP settings for sending mail.
my $smtp_user = 'system@domain.com';
my $smtp_passwd = "SetMe";
my $smtp_server = "localhost";

#Your AWS login information.
$ENV{'AWS_ACCESS_KEY_ID'} = 'SetMe';
$ENV{'AWS_SECRET_ACCESS_KEY'} = 'SetMe';

### Shouldn't need to edit anything below this line ###

my $backupCommand = "$duplicity --encrypt-key=$gpg_key --sign-key=$gpg_key ";
foreach my $dir (@backup_folders) {
    $backupCommand .= "--include $dir ";
}
$backupCommand .= "--exclude '**' / s3+http://$s3_bucketname";

my $cleanupCommand1;
my $cleanupCommand2;
if ($force) {
    $cleanupCommand1 = "$duplicity --force --remove-older-than $older_than s3+http://$s3_bucketname";
    $cleanupCommand2 = "$duplicity --force --cleanup s3+http://$s3_bucketname";
}
else {
    $cleanupCommand1 = "$duplicity --remove-older-than $older_than s3+http://$s3_bucketname";
    $cleanupCommand2 = "$duplicity --cleanup s3+http://$s3_bucketname";
}

#Dump database
system( "$pg_dumpall -U $db_user > $db_backup_dir/$db_backup_filename" );
if ( !$? ) {
    $backupOut .= "Dump of PostgreSQL Succeeded!\n\n";
} 
else {
    $subject .= "Error - ";
    $backupOut .= "Dump of PostgreSQL Failed!\n\n";
}
#End of Dump database

#Run Duplicity
open(BACKUPCMD, "$backupCommand 2>&1 |") or die "can't fork: $!";

#Grab output of Duplicity and check for errors
while (<BACKUPCMD>) {
    $backupOut .= $_, "\n";
    print $_;
    if ( $_ =~ m/^Error/ ) {
        my $line = $_;
        chomp($line);
        my @result = split(/ /, $line);

        if ( $result[1] != 0 ) {
            $subject .= "Error - ";
        }
    }
    elsif ( $_ =~ m/Error/ ) {
        $subject .= "Error - ";
    }
    elsif ( $_ =~ m/Traceback/ ) {
        $subject .= "Error - ";
    }
}
close(BACKUPCMD) or die "Can't close backup command: $! $?";

#Check for old files based on $older_than. Delete older files if $force is set to non-zero.
open(CLEANUPCMD1, "$cleanupCommand1 2>&1 |");
my $cleanupOut = "\nChecking for old files:\n";
while (<CLEANUPCMD1>) {
    $cleanupOut .= $_, "\n";
}
close(CLEANUPCMD1);

#Check for orphaned files. Delete orphaned files if $force is set to non-zero.
$cleanupOut .= "\nChecking for files that can be deleted:\n";
open(CLEANUPCMD2, "$cleanupCommand2 2>&1 |");
while (<CLEANUPCMD2>) {
    $cleanupOut .= $_, "\n";
}
close(CLEANUPCMD2);

#Email body
my $message = $backupOut . "\n" . $cleanupOut;

#Unset enviroment variables
$ENV{'AWS_ACCESS_KEY_ID'} = "";
$ENV{'AWS_SECRET_ACCESS_KEY'} = "";
$ENV{'PASSPHRASE'}= "";

#Create and send email
my $dateTime = `date`;
chomp($dateTime);
$subject .= "Backup to Amazon S3 at $dateTime";

my $msg = MIME::Lite->new(  
    From => $smtp_user,  
    To => join(',', @to_email),  
    Subject => $subject,  
    Data => $message  
);
MIME::Lite->send(
    'smtp', 
    $smtp_server, 
    AuthUser=>$smtp_user,
    AuthPass=>$smtp_passwd, 
    Timeout => 60
);
$msg->send;

Resources

Tip of the Day - Listing Installed Packages in Ubuntu

Posted by Ben Allen Mon, 22 Oct 2007 02:20:00 GMT

To list all installed packages in Ubuntu, simply run the following command:

 dpkg --get-selections

Thats it.

Tip of the Day - Fiesty to Gusty Ubuntu Server Upgrade

Posted by Ben Allen Sat, 20 Oct 2007 01:32:00 GMT

Well we upgraded this server to Gusty yesterday and it went without a hitch except for one problem.

First if you haven't seen how to upgrade Ubuntu Server from Feisty Fawn to Gutsy Gibbon check out this site: Gusty Upgrades. Its an extremely simple process.

The only problem we had is that the upgrade failed on upgrading the package clamsmtp. I have no idea why and there was no meaningful error displayed. All I did after it failed was to remove the clamsmtp package (we don't use it anymore anyways), and then I ran apt-get autoremove to remove a few packages there were marked for removal. Lastly just to make sure everything was upgraded, I did also run apt-get dist-upgrade but there were no more packages to upgrade.

Your milage is likely to vary if your upgrade fails, but it seemed for me that the system was in stable condition after the failure, and after a quick restart this was verified.

Overall Ron and I are very pleased with the upgrade process and with Gusty Gibbon.

Bravo Ubuntu.