Easier Rails in Ubuntu 7.04 beta 4/1/2007
With the upcoming release of Ubuntu 7, Apache 2.2 will be included in the standard package manager, meaning we no longer have to work in a hybrid managed and from-source environment to get a proper Rails stack up and running. Apache 2.2 added mod_proxy, giving us access to the ProxyBalancer directive that allows Apache to serve as a frontend to several Mongrel application servers.
Here is a quick-and-dirty guide to installing my application stack:
- Ubuntu 7.04 beta
- Apache 2.2 with mod_rewrite and mod_proxy
- Mongrel 1.0.1
- MySQL 5 (finally)
- Ruby 1.8.5 and Rails 1.2.3
For starters, get yourself a copy of Ubuntu 7.04 beta and get it installed. No one should have to give you directions on that part. Once that's up and running, we need to turn it into a development environment, so fire up a terminal and bang out the following:
$ sudo apt-get install build-essential
Now open Synaptic Package Manager and select and install mysql-server, libmysqlclient15-dev, ruby, irb, rdoc, ruby1.8-dev, and rubygems. Accept all the dependencies it alerts you to, and move on. Its very important you get ruby1.8-dev installed, or rubygems will not work correctly. I believe this to be an error in Synaptic, but we have to deal.
Now get back to the command line. Using Ruby's Gem installer, its time to finish up the Rails side of our stack. This part is similar to my previous howto for Ubuntu 6.
$ sudo gem install rails --include-dependencies $ sudo gem install mysql $ sudo gem install daemons gem_plugin mongrel mongrel_cluster --include-dependencies
Again, accept the dependencies it asks you to build, and accept the highest-versioned, non-win32 option in the menus. At this point you have a fully-functioning Rails environment, so test it out. Start a new rails app and configure a cluster like this:
$ mkdir ~/rails ; cd ~/rails ; rails www $ mongrel_rails cluster::configure -p 8001 -a 127.0.0.1 -N 3 $ mongrel_rails cluster::start
Test it out by browsing to http://127.0.0.1:8001/ and you should see the Rails welcome screen. If not, you've got something screwy happening and you should ask about it in the comments.
Now its time to get our Apache 2.2 frontend running. Start by using Synaptic to install apache2 (and its dependencies). If you like, include PHP or whatever else you think will be fun. After you've got it all installed, run these commands to enable mod_rewrite and mod_proxy:
$ sudo a2enmod rewrite $ sudo a2enmod proxy $ sudo a2enmod proxy_balancer $ sudo /etc/init.d/apache2 restart
Now add a line to the bottom of /etc/apache2/apache2.conf that directs Apache to your configuration file, which I store in ~/conf/httpd.conf.
Include /home/rcrowley/conf/httpd.conf
In this new config file, wherever you put it, place the following code (replacing whatever you need with new values):
NameVirtualHost *:80 <VirtualHost *:80> ServerName richarddcrowley.org Include /home/rcrowley/conf/www.conf </VirtualHost> <VirtualHost *:80> ServerName www.richarddcrowley.org Include /home/rcrowley/conf/www.conf </VirtualHost>
I choose to link out to another config file to keep from repeating myself when configuring both with-www and without-www versions of my sites. In the new file:
DocumentRoot /home/rcrowley/rails/www/public
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://www_mongrel%{REQUEST_URI} [P,QSA,L]
<Proxy balancer://www_mongrel>
BalancerMember http://127.0.0.1:8001
BalancerMember http://127.0.0.1:8002
BalancerMember http://127.0.0.1:8003
</Proxy>
Now you’re pretty much done, but its likely throwing 403 errors at you for most any request. Since this is undesirable behavior, you need to edit /etc/apache2/mods-available/proxy.conf. I found this method to be less-than-helpful, so I commented every line in the file out, restarted Apache, and life became better.
The last thing necessary is making your Mongrel cluster start up with your machine. This is exactly like last time. Create /etc/init.d/mongrel and put this in it:
#! /bin/sh
do_start()
{
echo "Starting Mongrel..."
mongrel_rails cluster::start -C ~rcrowley/rails/www/config/mongrel_cluster.yml
}
do_stop()
{
echo "Stopping Mongrel..."
mongrel_rails cluster::stop -C ~rcrowley/rails/www/config/mongrel_cluster.yml
}
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
restart|force-reload)
do_stop
do_start
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
exit 3
;;
esac
Now make it run on startup:
$ sudo update-rc.d mongrel defaults
Go forth and hack.
My new friend on the command line 2/23/2007
Out of the box, so to say, Linux is missing a way to conveniently swap files. To my knowledge there's no single command that will take a.txt and put its contents in b.txt while doing the reverse for the content in b.txt. Because I'm tweaking bits of code all the time and don't want to always rely on rolling back my Mercurial repository, I created this tiny script to make the world right again.
#!/bin/sh
if test -z "$1"
then
echo "Usage: swap file1 [file2]"
exit 1
fi
A=$1
if test -z "$2"
then
B="$1.sav"
else
B=$2
fi
mv $A /tmp/swap_tmp
mv $B $A
mv /tmp/swap_tmp $B
In two-argument mode it takes care of exactly the scenario above. But because I additionally use the .sav extension to files when working on two copies of the same file, I added a one argument mode to save a few more keystrokes.
This works extra nice if you have a ~/bin directory and add this to your ~/.bash_profile script:
if [ -d ~/bin ] ; then
PATH=~/bin:"${PATH}"
fi
Ruby on Rails from source on Ubuntu 1/15/2007
Update: Now that Ubuntu 7.04 beta is out, I tackled this problem again: Easier Rails in Ubuntu 7.04 beta.
A few weeks back I started playing a lot with Rails and got hooked. Everything that I had hacked before was just part of the workflow in Rails. In a bit of good timing, I broke my webserver while trying to upgrade X11 on Gentoo. Clearly it was time to start from scratch and to try Ubuntu. What follows is my way of getting from a blank Ubuntu install to a solid LAMP stack plus Ruby on Rails.
Format notes: a backslash (\) indicates a long line that I wrapped, a $ is a regular terminal and a # is a superuser terminal.
Gathering the pieces
$ su # cd ~ # apt-get install zlib1g-dev # wget ftp://ftp.ruby-lang.org/pub/ruby/ruby-1.8.5\ -p12.tar.gz # tar xzf ruby-1.8.5-p12.tar.gz # cd ruby-1.8.5-p12 # ./configure # make && make install # apt-get install postfix # apt-get install mysql-server mysql-common \ mysql-client libmysqlclient15-dev libmysqlclient15off # apt-get install libmysql-ruby1.8 # wget http://rubyforge.org/frs/download.php/\ 11289/rubygems-0.9.0.tgz # tar xzf rubygems-0.9.0.tgz # cd rubygems-0.9.0 # ruby setup.rb # cd ~ # gem install rails --include-dependencies # gem install mysql # gem install daemons gem_plugin mongrel \ mongrel_cluster --include-dependencies # wget http://apache.mirror99.com/httpd/\ httpd-2.2.4.tar.bz2 # tar xjf httpd-2.2.4.tar.bz2 # cd httpd-2.2.4 # ./configure --enable-deflate --enable-proxy \ --enable-proxy-balancer --enable-http --enable-info \ --disable-cgi --enable-rewrite --enable-so # make && make install
Apache startup script
# vi /etc/init.d/apache
The apache init script should look something like this:
#! /bin/sh
do_start()
{
echo "Starting apache..."
/usr/local/apache2/bin/apachectl start
}
do_stop()
{
echo "Stopping apache..."
/usr/local/apache2/bin/apachectl stop
}
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
restart|force-reload)
do_stop
do_start
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
exit 3
;;
esac
Rails setup
As Steven pointed out in the comments, I missed a step. If you have previously built Rails apps, now is the time to copy them onto your Ubuntu system and remember where they are. If you're really starting from scratch, the following command will give you a fresh Rails app called "www" to play with.
$ mkdir ~/rails ; cd ~/rails ; rails wwwThat last command,
rails www is where the magic happens. That generates the skeleton of a Rails app for you to fill in. See OnLamp for a good intro to building a Rails app.
Mongrel cluster wrangling
Before we can serve a Rails app properly, we need a Mongrel cluster. These steps are nearly verbatim what is prescribed by Coda Hale. I find it to be pretty tasty, myself.$ cd ~/rails/www $ mongrel_rails cluster::configure -p 8001 \ -a 127.0.0.1 -N 3 $ mongrel_rails cluster::startNow would be a good time to test the URL http://127.0.0.1:8001/ in a browser to see your Rails app working properly. Once it is, stop the cluster so we can setup the script that will start it at boot. This is pretty much exactly like the apache script (which is pretty much exactly like the Ubuntu skeleton script).
$ mongrel_rails cluster::stop # cp /etc/init.d/apache /etc/init.d/mongrel # vi /etc/init.d/mongrel
4,5c4,5 < echo "Starting apache..." < /usr/local/apache2/bin/apachectl start --- > echo "Starting mongrel cluster..." > mongrel_rails cluster::start -C ~rcrowley/\ rails/www/config/mongrel_cluster.yml 9,10c9,10 < echo "Stopping apache..." < /usr/local/apache2/bin/apachectl stop --- > echo "Stopping mongrel cluster..." > mongrel_rails cluster::stop -C ~rcrowley/\ rails/www/config/mongrel_cluster.yml
Install the init scripts
# update-rc.d apache defaults # update-rc.d mongrel defaults
Put the puzzle together
Again following the gospel according to Coda, this is how to beat the entire system together. First uncomment the line that includesconf/extra/httpd-vhosts.conf in the main apache conf/httpd.conf file. Then we can setup virtual hosts in that file. Something like
NameVirtualHost *:80 <VirtualHost *:80> ServerName richarddcrowley.org Include conf/extra/www.conf </VirtualHost> <VirtualHost *:80> ServerName www.richarddcrowley.org Include conf/extra/www.conf </VirtualHost>
will do just fine. You'll notice that I left a lot out by including conf/extra/www.conf. Indeed. That is where we'll do all the fun stuff:
DocumentRoot /home/rcrowley/rails/www/public
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://www_mongrel\
%{REQUEST_URI} [P,QSA,L]
<Proxy balancer://www_mongrel>
BalancerMember http://127.0.0.1:8001
BalancerMember http://127.0.0.1:8002
BalancerMember http://127.0.0.1:8003
</Proxy>
Now the Rails part of the config is done, so restart!
# /etc/init.d/apache restart
It works, right? Of course it does. I'll leave the "why" to experts but this is a fine "how" for making your Ubuntu box a sort of web server Swiss Army knife.
As a bonus, I have installed PHP 5.2 from source as well. PHP is better for hacking things together, so we have to keep it around. Before you run back to the command line, use Synaptic to make sure libcurl and libxml2 are installed, as any self-respecting PHP install will need those.
# wget http://us2.php.net/get/php-5.2.0.\ tar.bz2/from/this/mirror # tar xjf php-5.2.0.tar.bz2 # cd php-5.2.0 # ./configure --disable-cgi --with-libxml-dir \ --with-apxs2=/usr/local/apache2/bin/apxs \ --with-curl --with-mysql --with-mysqli \ --with-pdo-mysql --with-pear # make && make install
We're really done now. You now have a LAMPR server!
Awesome Error Message 9/18/2006
Innocently trying to print some code for a homework assignment, I was assualted today with the following error message by a computer on campus:[rdc3@beetle p7]$ scp * rcrowley@richarddcrowley.org:~/classes/cse422s/hw2/p7/ unknown user 10474 [rdc3@beetle p7]$ scp ./* rcrowley@richarddcrowley.org:~/classes/cse422s/hw2/p7/ unknown user 10474 [rdc3@beetle p7]$ ssh rcrowley@richarddcrowley.org You don't exist, go away! [rdc3@beetle p7]$
I love you too, CEC.