Ruby on Rails requires:
I have closely followed the instructions of the book “Agile Web Development With Rails” to get Ruby on Rails installed.
Of course, Ruby on Rails needs Ruby.
[root@1038 src]# wget http://rubyforge.org/frs/download.php/7858/ruby-1.8.4.tar.gz
From here one, just do the usual open-source build:
[root@1038 src]# cd ruby-1.8.4 [root@1038 ruby-1.8.4]# ./configure [root@1038 ruby-1.8.4]# make [root@1038 ruby-1.8.4]# make test [root@1038 ruby-1.8.4]# make install
The book tells you exactly how to install Rails. Here's an example:
[root@1038 woordenweb]# gem install rails Attempting local installation of 'rails' Local gem file not found: rails*.gem Attempting remote installation of 'rails' Updating Gem source index for: http://gems.rubyforge.org Install required dependency activerecord? [Yn] Y Install required dependency actionpack? [Yn] Y Install required dependency actionmailer? [Yn] Y Install required dependency actionwebservice? [Yn] Y Successfully installed rails-1.1.5 Successfully installed activerecord-1.14.4 Successfully installed actionpack-1.12.4 Successfully installed actionmailer-1.2.4 Successfully installed actionwebservice-1.1.5 Installing RDoc documentation for activerecord-1.14.4... Installing RDoc documentation for actionpack-1.12.4... Installing RDoc documentation for actionmailer-1.2.4... Installing RDoc documentation for actionwebservice-1.1.5...
I have installed RubyGems as per the book. After that, I tested the Ruby on Rails installation by using the Ruby based webrick server:
[root@1038 demo]# ruby script/server => Booting WEBrick... => Rails application started on http://0.0.0.0:3000 => Ctrl-C to shutdown server; call with --help for options [2006-05-02 09:50:28] INFO WEBrick 1.3.1 [2006-05-02 09:50:28] INFO ruby 1.8.4 (2005-12-24) [i686-linux] [2006-05-02 09:50:28] INFO WEBrick::HTTPServer#start: pid=14537 port=3000
Apparently, Ruby on Rails also needs the “MySQL Gem”.
[root@1038 depot]# gem install mysql Attempting local installation of 'mysql' Local gem file not found: mysql*.gem Attempting remote installation of 'mysql' Updating Gem source index for: http://gems.rubyforge.org Select which gem to install for your platform (i686-linux) 1. mysql 2.7.2006.04.21 (mswin32) 2. mysql 2.7 (ruby) 3. mysql 2.6 (ruby) 4. mysql 2.5.1 (ruby) 5. Cancel installation > 2 Building native extensions. This could take a while... ruby extconf.rb install mysql checking for mysql_query() in -lmysqlclient... yes checking for mysql_ssl_set()... yes checking for mysql.h... no checking for mysql/mysql.h... yes creating Makefile make gcc -fPIC -g -O2 -I. -I/usr/local/lib/ruby/1.8/i686-linux -I/usr/local/lib/ruby/1.8/i686-linux -I. -DHAVE_MYSQL_SSL_SET -DHAVE_MYSQL_MYSQL_H -I/usr/local/include -c mysql.c gcc -shared -L'/usr/local/lib' -Wl,-R'/usr/local/lib' -L'/usr/local/lib' -Wl,-R'/usr/local/lib' -o mysql.so mysql.o -lmysqlclient -ldl -lcrypt -lm -lc make install mkdir -p /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/lib /usr/bin/install -c -m 0755 mysql.so /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/lib Successfully installed mysql-2.7
On another system, I had troubles getting the mysql gem installed.
A posting on weblog.rubyonrails.com, weblog.rubyonrails.com, suggested this: ruby extconf.rb –with-mysql-dir=/opt/lampp/bin
, but that lead to this output:
daforeignmachine:/opt/lampp/lib/ruby/gems/1.8/gems/mysql-2.7 # ruby extconf.rb --with-mysql-dir=/opt/lampp /bin checking for mysql_query() in -lmysqlclient... no checking for main() in -lm... yes checking for mysql_query() in -lmysqlclient... no checking for main() in -lz... yes checking for mysql_query() in -lmysqlclient... no checking for main() in -lsocket... no checking for mysql_query() in -lmysqlclient... no checking for main() in -lnsl... yes checking for mysql_query() in -lmysqlclient... no *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options. Provided configuration options: --with-opt-dir --without-opt-dir --with-opt-include --without-opt-include=${opt-dir}/include --with-opt-lib --without-opt-lib=${opt-dir}/lib --with-make-prog --without-make-prog --srcdir=. --curdir --ruby=/opt/lampp/bin/ruby --with-mysql-config --without-mysql-config --with-mysql-dir --with-mysql-include --without-mysql-include=${mysql-dir}/include --with-mysql-lib --without-mysql-lib=${mysql-dir}/lib --with-mysqlclientlib --without-mysqlclientlib --with-mlib --without-mlib --with-mysqlclientlib --without-mysqlclientlib --with-zlib --without-zlib --with-mysqlclientlib --without-mysqlclientlib --with-socketlib --without-socketlib --with-mysqlclientlib --without-mysqlclientlib --with-nsllib --without-nsllib --with-mysqlclientlib --without-mysqlclientlib
My hypothesis is: the mysql client developer's libraries are not installed. A little web searching yields this result:
“Those errors are usually caused by one of those two things: gcc is not installed or libmysqlclient14-dev (mysql client developer’s libraries) are not installed.”
Lazycoder blog: Ruby on rails error
In my case, I had to install the mysql client developer’s libraries.
Turns out that Rails wants the mysql.sock
file in a specific place, namely /tmp/mysql.sock
. If your mysql.sock file is located elsewhere, simply make a symbolic link to the actual location. E.g.:
myhost:/tmp# ln -s /var/run/mysqld/mysqld.sock mysql.sock myhost:/tmp# ls -lah total 816K drwxrwxrwt 5 root root 1.0K Jul 18 19:10 . drwxr-xr-x 20 root root 1.0K May 10 01:10 .. lrwxrwxrwx 1 root root 27 Jul 18 16:08 mysql.sock -> /var/run/mysqld/mysqld.sock
However, /tmp/
being what it is (a temporary directory), its content tends to get deleted every once in a while. So a much better solution is the following:
Just specify the correct path to the socket in config/database.yml
!
Example:
production: adapter: mysql database: myproject_production encoding: utf8 username: myproject_user password: host: localhost socket: /var/run/mysqld/mysqld.sock
For real life production servers, it is recommended to use FastCGI. Because I had Apache already running, I decided to install FastCGI as an Apache module.
This website deals (not exclusively) with installing FastCGI for Ruby on Rails:
http://www.easy-designs.net/articles/WesthostOnRails/
It is almost entirely correct, except for the changes which the author recommends for the file dispatch.fcgi
.
Installing FastCGI was not exactly easy and because I am afraid the afore mentioned website may one day disappear, I have copied some instructions verbatimly.
We need to install the FastCGI Dev Kit. To do that, enter its directory, configure and install it similarly to how we did Ruby:
[~]$ cd fcgi-2.4.0 [fcgi-2.4.0]$ ./configure --prefix=/usr/local/fcgi [fcgi-2.4.0]$ make && make install
Next on the agenda is getting Apache to understand FastCGI. To do this, we need to compile and install the DSO for Apache, which uses a slightly different process:
[root@1038 mod_fastcgi-2.4.2]# /www/bin/apxs -i -a -n fastcgi mod_fastcgi.so [activating module `fastcgi' in /www/conf/httpd.conf] cp mod_fastcgi.so /www/libexec/mod_fastcgi.so chmod 755 /www/libexec/mod_fastcgi.so cp /www/conf/httpd.conf /www/conf/httpd.conf.bak cp /www/conf/httpd.conf.new /www/conf/httpd.conf rm /www/conf/httpd.conf.new [root@1038 mod_fastcgi-2.4.2]#
Then install the Ruby-FastCGI Gem:
[root@1038 bin]# gem install fcgi Attempting local installation of 'fcgi' Local gem file not found: fcgi*.gem Attempting remote installation of 'fcgi' Building native extensions. This could take a while... ruby extconf.rb install fcgi checking for fcgiapp.h... yes checking for FCGX_Accept() in -lfcgi... yes creating Makefile make gcc -fPIC -g -O2 -I. -I/usr/local/lib/ruby/1.8/i686-linux -I/usr/local/lib/ruby/1.8/i686-linux -I. -DHAVE_FCGIAPP_H -c fcgi.c gcc -shared -L'/usr/local/lib' -Wl,-R'/usr/local/lib' -o fcgi.so fcgi.o -lfcgi -ldl -lcrypt -lm -lc make install /usr/bin/install -c -m 0755 fcgi.so /usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.6.1/. Successfully installed fcgi-0.8.6.1 Installing RDoc documentation for fcgi-0.8.6.1... No definition for fcgi_s_accept (... same kind of messages ...) No definition for fcgi_stream_setsync
We need to add the handler for FastCGI to httpd.conf, so scroll down in this file until you see some other AddHandler statements (or run a search) and insert the following:
AddHandler fastcgi-script fcg fcgi fpl
Then, create an instance of our demo app near the bottom of the httpd.conf file:
# FastCGI <IfModule mod_fastcgi.c> FastCgiIpcDir /tmp/fcgi_ipc FastCgiServer /home/solin/domains/rails.solin.nl/demo/public/dispatch.fcgi -initial-env RAILS_ENV=development -processes 1 -idle-timeout 60 #FastCgiServer /home/solin/domains/rails.solin.nl/demo/public/dispatch.fcgi -initial-env RAILS_ENV=production -processes 1 -idle-timeout 60 </IfModule>
I have experimented with the above settings. They refer directly to specific virtual hosts, which is very inconvenient. You can leave them out. You probably only need the line FastCgiIpcDir /tmp/fcgi_ipc
.
A further addition is the entry for our demo website:
<VirtualHost 213.193.214.124:80> ServerName rails.solin.nl ServerAlias www.rails.solin.nl DocumentRoot /home/solin/domains/rails.solin.nl/demo/public ErrorLog /home/solin/domains/rails.solin.nl/logs/error_log CustomLog /home/solin/domains/rails.solin.nl/logs/access_log combined <Directory /home/solin/domains/rails.solin.nl/demo/public> Options ExecCGI FollowSymLinks AllowOverride all Allow from all Order allow,deny </Directory> </VirtualHost>
The section within ”<Directory>
” is very important: Ruby on Rails depends on .htaccess
files for rewriting url. In other words: ”AllowOverride all
” is crucial.
Now, to set up Rails to use FastCGI, we need to edit the .htaccess file in the public folder. In that file, change:
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
to:
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
That's it. Do not make the changes in the file dispatch.fcgi
as the author of the website recommends.
Test the configuration:
[root@1038 bin]# /www/bin/apachectl configtest [Mon May 1 20:38:18 2006] [warn] module mod_fastcgi.c is already added, skipping [Mon May 1 20:38:18 2006] [warn] NameVirtualHost 213.193.214.125:80 has no VirtualHosts Syntax OK
And restart Apache:
[root@1038 bin]# /www/bin/apachectl restart /www/bin/apachectl restart: httpd restarted
An alternative method for improving Rails' speed is scgi.
Start scgi processes through:
host:/rails_apps/my_app/ # scgi_ctrl start
Please remember that your Rails application also contains a config/scgi.yaml
file. Do not forget to back up this file if you ever reinstall your Rails app.
Nowadays, people don't use FastCGI anymore apparently. Mongrel provides far better performance it is rumored (okay, people have run tests to figure this out – see Google). A popular way of installing and configuring Rails is:
I have Apache 2.0.x on my Debian Stable (Sarge) host, so I can't use Apache's load balancing facilities. Instead, I use Pen. To get my Rails applications to run fast on Debian Sarge, I followed the instructions on this website:
Mongrel, Apache and Rails on Debian Sarge
I had relatively little trouble getting it all installed. There's one minor annoyance though: Mongrel is really interwoven with your Rails app, just like your local Webrick webserver. If your Rails app is not properly installed, the Mongrel “instance” for your application will not run.
To follow the instructions on the website mentioned above, I had to install the mod_enabled Apache module. I used the a2enmod
command to do this.
root@lappy:~# a2enmod enabled Module enabled installed; run /etc/init.d/apache2 force-reload to enable.
It's also nice to see a complete working example of an Apache virtual host section so here goes:
<VirtualHost *:80> ServerName smallcount.myhost.com ServerAlias www.smallcount.myhost.com DocumentRoot /home/myhost/domains/smallcount.myhost.com/smallcount/public ## Fix for Apache bug 39499 #SetEnv force-proxy-request-1.0 1 #SetEnv proxy-nokeepalive 1 ## mod_proxy config ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy> ## send all requests to URIs not corresponding to real files to the load balancer: RewriteEngine On RewriteRule ^/$ /index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f ## 8001 is the proxy_port from mongrel configuration of your app RewriteRule .* http://localhost:8001%{REQUEST_URI} [P,QSA] </VirtualHost>
(Please remember to restart your Apache webserver after changing the configuration files).
First you have to know how to start mongrel. Mongrel lives in /etc/mongrel
. The websites powered by mongrel are defined in /etc/mongrel/sites-enabled
. Start mongrel like this:
/etc/mongrel/sites-enabled# /etc/init.d/mongrel restart YOUR_SITE_CONFIG_FILE.cfg
If anything goes wrong, try to start your website manually so you'll see mongrel's output. Example:
/etc/mongrel/sites-enabled# /usr/bin/ruby1.8 /usr/bin/mongrel_rails start -e production -a 127.0.0.1 -c /home/myhost/domains/mysite.myhost.com/mysite ** Starting Mongrel listening at 127.0.0.1:3000 ** Starting Rails with production environment... /usr/lib/ruby/1.8/yaml.rb:133:in `load': syntax error on line 16, col 11: ` encoding: utf8' (ArgumentError)
The short version: simply increase all port numbers in all configurations files. As an example, here's the smallcount.conf
mongrel configuration file for the example app mentioned above:
# RAILS_ROOT of your application dir=/myhome/myhost/domains/smallcount.myhost.com/smallcount/public # port the first mongrel instance should listen to, additional instances will use ports above this port=8100 # number of mongrel instances servers=3 # port pen will listen on proxy_port=8001
Remember the proxy port, because that's the one we're gonna reference in the Apache virtual host configuration file:
ServerName smallcount.myhost.com ServerAlias www.smallcount.myhost.com DocumentRoot /myhome/myhost/domains/smallcount.myhost.com/smallcount/public ## Fix for Apache bug 39499 #SetEnv force-proxy-request-1.0 1 #SetEnv proxy-nokeepalive 1 ## mod_proxy config ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy> ## send all requests to URIs not corresponding to real files to the load balancer: RewriteEngine On RewriteRule ^/$ /index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f ## 8001 is the proxy_port from mongrel configuration of your app RewriteRule .* http://localhost:8001%{REQUEST_URI} [P,QSA]
Now if you add a second rails application, just increase all the port numbers by one:
# RAILS_ROOT of your application dir=/myhome/myhost/domains/woordenweb.myhost.com/woordenweb/public # port the first mongrel instance should listen to, additional instances will use ports above this port=8200 # number of mongrel instances servers=3 # port pen will listen on proxy_port=8002
And in your Apache configuration file too:
ServerName woordenweb.myhost.com ServerAlias www.woordenweb.myhost.com DocumentRoot /myhome/myhost/domains/woordenweb.myhost.com/woordenweb/public ## Fix for Apache bug 39499 #SetEnv force-proxy-request-1.0 1 #SetEnv proxy-nokeepalive 1 ## mod_proxy config ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy> ## send all requests to URIs not corresponding to real files to the load balancer: RewriteEngine On RewriteRule ^/$ /index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f ## 8002 is the proxy_port from mongrel configuration of your app RewriteRule .* http://localhost:8002%{REQUEST_URI} [P,QSA]
Here's how to run two (or more) rails applications with Mongrel.
httpd-vhosts.conf
file and restart Apache1. Install Mongrel:
sudo gem install mongrel
Then move to the directory where your rails app is in (the directory just above app
). Now, issue this command:
mongrel_rails start -d -p 8000 -e production
The -d
options means 'daemonize' (or detach). If you don't use this option, the mongrel instance will shut down once you exit your terminal.
Repeat for each app, but increase the port number by 1 each time, and remember the port numbers for each app.
If you're ready, issue this command: ps -ef |grep mongrel
. You should see all your mongrel instances now:
> ps -ef |grep mongrel root 20733 1 0 21:00 ? 00:00:04 /opt/lampp/bin/ruby /opt/lampp/bin/mongrel_rails start -e development -d -p 8002 root 20862 1 0 21:59 ? 00:00:02 /opt/lampp/bin/ruby /opt/lampp/bin/mongrel_rails start -d -p 8003 -e production
N.B.: try to avoid running the mongrels as root.
2. Your applications are going to served up by Apache first. Apache should handle all the static content (images, stylesheets, javascripts, flash files, etc.), and pass on all dynamic requests to mongrel. So, you're going to need mod_proxy. Here's an example of a virtual host entry in httpd-vhosts.conf
file:
<VirtualHost *:80> ServerName suppappa.com ServerAlias www.suppappa.com DocumentRoot /path/to/rails_app/suppappa/public ProxyPass / http://suppappa.com:8002/ ProxyPassReverse / http://suppappa.com:8002 ProxyPreserveHost on ProxyPass /images ! ProxyPass /stylesheets ! ProxyPass /javascripts ! ProxyPass /flash ! #continue with other static files that should be served by apache Alias /images /path/to/rails_app/suppappa/public/images Alias /stylesheets /path/to/rails_app/suppappa/public/stylesheets Alias /javascripts /path/to/rails_app/suppappa/public/javascripts Alias /flash /path/to/rails_app/suppappa/public/flash #continue with aliases for static content </VirtualHost>
Now all you have to do is restart Apache (e.g. apachectl restart).
Debian / Ubuntu users attention! Make sure that proxy.conf is configured to allow reverse proxying! See the Apache 2.2 documentation for mod_proxy.
<IfModule mod_proxy.c> #turning ProxyRequests on and allowing proxying from all may allow #spammers to use your proxy to send email. ProxyRequests Off <Proxy *> Order deny,allow #Deny from all Allow from all </Proxy> # Enable/disable the handling of HTTP/1.1 "Via:" headers. # ("Full" adds the server version; "Block" removes all outgoing Via: headers) # Set to one of: Off | On | Full | Block ProxyVia On </IfModule>
The default for Debian / Ubuntu is Deny from all
, but that should be changed to Allow from all
.
N.B.: if you need to restart mongrel, just run mongrel_rails stop
and mongrel_rails start -e development -d -p 8002
(or whatever mode and port number you're using).
If you want to know which version you just installed, do rails -v
on the command line. If you want to know, 100% sure, which version of Rails your application is actually using, add this in one of your views:
Rails version: <%= RAILS_GEM_VERSION.to_s %>
To install a specific Rails version (instead of just the latest stable version), use the -v
parameter:
gem install rails -v 1.1.6
In the same way, you can also uninstall specific rails versions:
gem uninstall rails -v 1.2.0
To list all versions currently installed, do gem list rails
:
gem list rails *** LOCAL GEMS *** rails (1.2.2, 1.1.6) Web-application framework with template engine, control-flow layer, and ORM.
This is pretty straightforward. Just install the RoR package through the Synaptic Package Manager, as well as RubyGems (manual installation only, download here).
Finally, you must also install libmysql-ruby using the Synaptic Package Manager. That's it.
Follow the instructions from the guys from Phusion: www.modrails.com. There are several pitfalls:
PassengerDefaultUser
(inside a <VirtualHost>) to your Apache user (e.g. www-data
)RailsEnv development
(inside a <VirtualHost>) to set it to development mode.That's it.
Install Ruby Enterprise to complement modrails. From the nice guys of Phusion!
Only possible issue: Ruby Enterprise is installed completely separately from your existing Ruby stuff. So, all your currently installed gems are not used by Ruby Enterprise. According to this site, you can do:
/opt/ruby-enterprise-1.8.6-20080810/bin/gem install mislav-will_paginate
Or you can symlink to the correct version:
ln -fs /opt/ruby-enterprise-1.8.6-20080810 /opt/ruby-enterprise ln -fs /opt/ruby-enterprise/bin/gem /usr/bin/gem ln -fs /opt/ruby-enterprise/bin/irb /usr/bin/irb ln -fs /opt/ruby-enterprise/bin/rake /usr/bin/rake ln -fs /opt/ruby-enterprise/bin/rails /usr/bin/rails ln -fs /opt/ruby-enterprise/bin/ruby /usr/bin/ruby