=====Installing and configuring Ruby on Rails===== Ruby on Rails requires: *Ruby (the programming language) *RubyGems (This the standard Ruby package manager. It's similar to apt-get, emerge, and other OS package managers.) I have closely followed the instructions of the book "Agile Web Development With Rails" to get Ruby on Rails installed. ===Compiling Ruby=== 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 ===Wrapping Up: RubyGems and Using Webrick=== 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 ====Installing the MySQL Gem==== 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 ===Problems with Installing the MySQL Gem=== On another system, I had troubles getting the mysql gem installed. A posting on weblog.rubyonrails.com, [[http://weblog.rubyonrails.com/2005/10/30/get-10-15-more-performance-with-mysql-rails/|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." [[http://www.lazycoder.com/weblog/index.php/archives/2005/07/06/ruby-on-rails-error/|Lazycoder blog: Ruby on rails error]] In my case, I had to install the mysql client developer’s libraries. ===More Trouble With MySQL=== 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: ===SOLVED: More Trouble With MySQL=== 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 ====Faster Ruby on Rails: FastCGI==== 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/|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. ===Installing FastCGI=== 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 ===Configuring Apache=== 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 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 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: 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 Options ExecCGI FollowSymLinks AllowOverride all Allow from all Order allow,deny The section within "''****''" 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 ====SCGI for faster Rails==== An alternative method for improving Rails' speed is [[http://www.zedshaw.com/projects/scgi_rails/|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. ====Mongrel for faster Rails (and Pen for better load balancing under Apache 2.0)==== 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: * Mongrel webserver * Apache webserver * A load balancing mechanism, e.g. as provided by Apache 2.2 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: [[http://www.jkraemer.net/2006/7/7/mongrel-apache-and-rails-on-debian-sarge|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: 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 Order deny,allow Allow from all ## 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] (Please remember to restart your Apache webserver after changing the configuration files). ===Testing and Troubleshooting Mongrel=== 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) ====Running Two (or more) Rails Applications with Mongrel==== 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 Order deny,allow Allow from all ## 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 Order deny,allow Allow from all ## 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] ====Simple Configuration for Running Two or More Applications with Mongrel under Apache 2.2==== Here's how to run two (or more) rails applications with Mongrel. - Start a Mongrel instance ('process') for each application - Configure your Apache ''httpd-vhosts.conf'' file and restart Apache 1. 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: 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 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 [[http://httpd.apache.org/docs/2.2/mod/mod_proxy.html|mod_proxy]]. #turning ProxyRequests on and allowing proxying from all may allow #spammers to use your proxy to send email. ProxyRequests Off Order deny,allow #Deny from all Allow from all # 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 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). =====Which Version?===== 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 %> =====Installing Other Rails Versions Using Gem===== 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. =====Rails on Ubuntu Linux===== This is pretty straightforward. Just install the RoR package through the Synaptic Package Manager, as well as RubyGems (manual installation only, [[http://rubygems.org/read/chapter/3|download here]]). Finally, you must also install libmysql-ruby using the Synaptic Package Manager. That's it. =====Phusion Passenger Under Ubuntu Linux===== Follow the instructions from the guys from Phusion: [[http://www.modrails.com/install.html|www.modrails.com]]. There are several pitfalls: * PassengerDefaultUser: if you experience starting problems, set ''PassengerDefaultUser'' (inside a ) to your Apache user (e.g. ''www-data'') * Delete old /tmp/ruby_sess.* files * Delete the .htaccess file from your Rails public directory (or the assets, such as images, will not show up) * Apparently, Phusion Passenger is not compatible with mod_rewrite / mod_alias. See: [[http://www.modrails.com/documentation/Users%20guide.html#_mod_rewrite_and_mod_alias|modrails.com]] * By default, mod_rails runs in production mode. Use ''RailsEnv development'' (inside a ) to set it to development mode. That's it. =====Ruby Enterprise===== 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 [[http://scottmotte.com/archives/389|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