Archive for the ‘Ruby On Rails’ Category

No such file or directory - /tmp/mysql.sock

Sunday, August 10th, 2008
No Gravatar

Today I started messing around with Rails again, after having spent the best part of the last months on Merb.

Anyway the common link problem for the mysql adapter reared its ugly head as usual.
No such file or directory - /tmp/mysql.sock

The solution to this is to create a symbolic link from your mysqld.sock to /tmp/mysql.sock

But where is your mysqld.sock?

For Mac OSX it is usually in /opt/local/var/run/mysql5/mysqld.sock.
Check where it is with locate.

locate mysqld.sock

Now create the symlink:
ln -s /link/to/where/mysqld.sock /tmp/mysql.sock
on my Mac, I ran:
ln -s /opt/local/var/run/mysql5/mysqld.sock /tmp/mysql.sock

Facebook Connect

Wednesday, July 30th, 2008
No Gravatar

Facebook Connect came out on the 23rd of this month, and is a much modified and improved version of the notorious Facebook Beacon.

It allows external sites to authenticate a user and share detailed information including friendships, albums and personal profiles through facebook.

It is facebooks alternative to OpenSocial (and a little bit of OpenID), and it is going to be huge!

If you want a Facebook Connect application, or a Facebook application written in Ruby on Rails or Merb, give us a call.

Interesting Times

Sunday, July 20th, 2008
No Gravatar

Green not Mean
Search Engine Optimisation with Wordpress plugins is pretty awesome. Heck I’m getting over 100 hits a day on a blog about the obscure. I’m impressed.

Anyway, I have now left Greenvoice, and Bablo, and it is time for a change.

What to do? Well I have a couple of ideas up my sleeve so watch this space or further info.

In the iterim, if you need a Rails / Merb / CTO / project manager / someone to talk at you, please feel free to contact me at jason dot green at (this website address).

Getting Rubyworks running with Nginx and Capistrano on Ubuntu 7.10 (Dapper Drake)

Thursday, November 22nd, 2007
No Gravatar

I want multiple apps running on one machine. Each app has a nginx server with 4 mongrels sitting behind it. Here is my setup:

1. Install Ubuntu 7.10, and sudo apt-get install subversion and sudo apt-get install mysql-server
2. Follow first page of Rubyworks install here: http://rubyworks.rubyforge.org/installation/ubuntu.html
3. Install Nginx by typing: sudo apt-get install nginx

4. Here is my nginx config for my first app, which I have saved in /etc/rails/my_first_app/nginx.conf

# user and group to run as
user jason jason;

# number of nginx workers
worker_processes 1;

# pid of nginx master process
pid /var/run/nginx_my_first_app.pid;

# Number of worker connections. 1024 is a good default
events {
worker_connections 1024;
use epoll; # linux only!
}

# start the http module where we config http access.
http {
# pull in mime-types. You can break out your config
# into as many include’s as you want to make it cleaner
include /etc/nginx/mime.types;

# set a default type for the rare situation that
# nothing matches from the mimie-type include
default_type application/octet-stream;

# configure log format
log_format main ‘$remote_addr - $remote_user [$time_local] ‘
‘”$request” $status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;

# main access log
access_log /var/www/apps/my_first_app/shared/log/nginx/access.log main;

# main error log - Do not comment out. If you do not want the log file set this to /dev/null
error_log /var/www/apps/my_first_app/shared/log/nginx/error.log notice;

# no sendfile on OSX
sendfile on;

# These are good default values.
tcp_nopush on;
tcp_nodelay on;
# output compression saves bandwidth
gzip on;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

# this is where you define your mongrel clusters.
# you need one of these blocks for each cluster
# and each one needs its own name to refer to it later.
upstream mongrel {
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
server 127.0.0.1:3004;
}

# uncomment if you want to always redirect to www.
#server {
# listen 80;
# server_name exmaple.com;
# rewrite ^.*$ http://www.example.com;
#}

# the server directive is nginx’s virtual host directive.
server {
# port to listen on. Can also be set to an IP:PORT
listen 3000;

# Set the max size for file uploads to 50Mb
client_max_body_size 50M;

# doc root
root /var/www/apps/my_first_app/current/public;

# vhost specific access log
access_log /var/www/apps/my_first_app/shared/log/nginx/vhost.access.log main;

# this allows people to use images and css in their maintenance.html file
if ($request_filename ~* \.(css|jpg|gif|png)$) {
break;
}

# this rewrites all the requests to the maintenance.html
# page if it exists in the doc root. This is for capistrano’s
# disable web task
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html last;
break;
}

location / {
index home.html index.html index.htm;
# needed to forward user’s IP address to rails
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
proxy_max_temp_file_size 0;

#location ~ ^/(images|javascripts|stylesheets)/ {
# expires 10y;
#}

if (-f $request_filename) {
break;
}

if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}

# this is the meat of the rails page caching config
# it adds .html to the end of the url and then checks
# the filesystem for that file. If it exists, then we
# rewite the url to have explicit .html on the end
# and then send it on its way to the next config rule.
# if there is no file on the fs then it sets all the
# necessary headers and proxies to our upstream mongrels
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}

if (!-f $request_filename) {
proxy_pass http://mongrel;
break;
}
}

error_page 400 /400;
error_page 500 502 503 504 /500.html;
location = /500.html {
root /var/www/apps/my_first_app/current/public;
}
location = /400 {
return 400;
}
}

}

5. In /etc/rails/my_first_app I also place 4 mongrel configs called mongrel_3001.confmongrel_3004.conf

With the following inside each one:


:cwd: /var/www/apps/my_first_app/current/
:log_file: /var/www/apps/my_first_app/shared/log/mongrels/mongrel_3001.log
:daemon: false
:debug: false
:environment: production
:port: 3001
:num_processors: 5

obviously thats the 3001 config, you need to modify 3001 to 3002 etc depending on which mongrel config it is (3001, 3002, 3003 or 3004)

6. Now to edit the services run by monit

First cd /var/service sudo rm -Rf mongrel* to remove current mongrel configs
Then sudo rm -Rf /var/service/haproxy to remove ha proxy
This leaves you with only monit

7. Do: sudo mkdir my_first_ap_mongrel_3001, sudo mkdir my_first_ap_mongrel_3002, sudo mkdir my_first_ap_mongrel_3003, sudo mkdir my_first_ap_mongrel_3004 and sudo mkdir my_first_ap_nginx_3000

8. Now create a run file (executable sudo chmod +x run) inside each of these directories with the following info:

For the mongrels:

#!/usr/bin/env ruby

# Doing it this way, instead of simple ’sudo -u rails exec …’ gets around a sudo bug in RHEL/CentOS 4,
# described in http://bugs.centos.org/view.php?id=1650

require ‘etc’

Process::GID.change_privilege(Etc.getgrnam(’rails’).gid)
Process::UID.change_privilege(Etc.getpwnam(’rails’).uid)

exec ‘/usr/bin/mongrel_rails start -c /usr/rails -C /etc/rails/my_first_app/mongrel_3001.config’

changing the number for which ever mongrel

and for nginx:

#!/bin/sh
exec /usr/sbin/nginx -c /etc/rails/my_first_app/nginx.conf

7. Nearly there! Now edit sudo vi /etc/rails/monit.conf

Delete it all and change it to this:

# Configuration for Monit, a monitoring tool
# whose role in RubyWorks stack is to ensure that other components
# are up and running at all times.
#
# Original documentation for Monit is here:
# http://www.tildeslash.com/monit/doc/manual.php

set daemon 15 # Perform a check every 15 seconds
set logfile /var/log/monit.log

# set mailserver mail.bar.com
# set alert admin@bar.com
# mail-format {
# from: rubyworks@rubyforge.org
# subject: $SERVICE $EVENT at $DATE
# message: Monit $ACTION $SERVICE at $DATE on $HOST,
#
# Yours sincerely,
# RubyWorks.
# }

# This section configures Monit’s web frontend on port http://localhost:80.
set httpd port 80 and
# only accept connection from localhost. Change to 0.0.0.0 to accept
# remote connections. Make sure to change the password in the ‘allow’
# statement if you do.
use address 0.0.0.0
# When someone connects to the web frontend, perform basic HTTP i
# authentication and accept username/password admin/MonitPa$$w0rd
allow admin/MonitPa$$w0rd

check process my_first_app_nginx_3000
with pidfile “/var/service/my_first_app_nginx_3000/supervise/pid”
start program = “/usr/bin/sv up my_first_app_nginx_3000″
stop program = “/usr/bin/sv down my_first_app_nginx_3000″
if totalmem is greater than 100.0 MB for 4 cycles then restart
if failed port 3001 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout

check process my_first_app_mongrel_3001
with pidfile “/var/service/my_first_app_mongrel_3001/supervise/pid”
group mongrels_my_first_app
start program = “/usr/bin/sv up my_first_app_mongrel_3001″
stop program = “/usr/bin/sv down my_first_app_mongrel_3001″
if totalmem is greater than 110.0 MB for 4 cycles then restart
if failed port 3002 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout

check process my_first_app_mongrel_3002
with pidfile “/var/service/my_first_app_mongrel_3002/supervise/pid”
group mongrels_my_first_app
start program = “/usr/bin/sv up my_first_app_mongrel_3002″
stop program = “/usr/bin/sv down my_first_app_mongrel_3002″
if totalmem is greater than 110.0 MB for 4 cycles then restart
if failed port 3002 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout

check process my_first_app_mongrel_3003
with pidfile “/var/service/my_first_app_mongrel_3003/supervise/pid”
group mongrels_my_first_app
start program = “/usr/bin/sv up my_first_app_mongrel_3003″
stop program = “/usr/bin/sv down my_first_app_mongrel_3003″
if totalmem is greater than 110.0 MB for 4 cycles then restart
if failed port 3002 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout

check process my_first_app_mongrel_3004
with pidfile “/var/service/my_first_app_mongrel_3004/supervise/pid”
group mongrels_my_first_app
start program = “/usr/bin/sv up my_first_app_mongrel_3004″
stop program = “/usr/bin/sv down my_first_app_mongrel_3004″
if totalmem is greater than 110.0 MB for 4 cycles then restart
if failed port 3002 for 3 times within 5 cycles then restart
if cpu is greater than 50% for 2 cycles then alert
if cpu is greater than 80% for 3 cycles then restart
if loadavg(5min) greater than 10 for 8 cycles then restart
if 20 restarts within 20 cycles then timeout

8. It’s now time to deploy!

Using your deploy file, here is mine as an example (place this in your rails project config/deploy.rb:

# =============================================================================
# ENGINE YARD REQUIRED VARIABLES
# =============================================================================
# You must always specify the application and repository for every recipe. The
# repository must be the URL of the repository you want this recipe to
# correspond to. The deploy_to path must be the path on each machine that will
# form the root of the application path.

set :keep_releases, 3
set :application, ‘my_first_app’
set :user, ‘jason’
set :password, ‘my password for my user’

set :repository, ‘https://my_svn.com/trunk’
set :svn_username, ‘jason’
set :svn_password, ‘hello svn password’
set :deploy_to, “/var/www/apps/#{application}”
set :checkout, “export”
set :monit_group, ‘mongrels_my_first_app’
set :use_sudo, true
set :rails_env, “production”

# =============================================================================
# ROLES
# =============================================================================
# You can define any number of roles, each of which contains any number of
# machines. Roles might include such things as :web, or :app, or :db, defining
# what the purpose of each machine is. You can also specify options that can
# be used to single out a specific subset of boxes in a particular role, like
# :primary => true.

task :production do
role :web, ‘ip_address_of_ubuntu_server’
role :app, ‘ip_address_of_ubuntu_server’
role :db, ‘ip_address_of_ubuntu_server’, :primary => true
end

# =============================================================================
# TASKS

desc “Long deploy will throw up the maintenance.html page and run migrations
then it restarts and enables the site again.”
task :long_deploy do
transaction do
update_code
migrate
end
restart
end

task :revision, :roles => :app do
run %(tail -1 #{deploy_to}/revisions.log)
end

desc <<-DESC
Restart the Mongrel processes on the app server by calling restart_mongrel_cluster.
DESC
task :restart, :roles => :app do
restart_mongrel_cluster
end

desc <<-DESC
Start the Mongrel processes on the app server by calling start_mongrel_cluster.
DESC
task :spinner, :roles => :app do
start_mongrel_cluster
end

desc <<-DESC
Start Mongrel processes on the app server. This uses the :use_sudo variable to determine whether to use sudo or not. By default, :use_sudo is
set to true.
DESC
task :start_mongrel_cluster , :roles => :app do
sudo “monit start all -g #{monit_group}”
end

desc <<-DESC
Restart the Mongrel processes on the app server by starting and stopping the cluster. This uses the :use_sudo
variable to determine whether to use sudo or not. By default, :use_sudo is set to true.
DESC
task :restart_mongrel_cluster , :roles => :app do
sudo “monit restart all -g #{monit_group}”
end

desc <<-DESC
Stop the Mongrel processes on the app server. This uses the :use_sudo
variable to determine whether to use sudo or not. By default, :use_sudo is
set to true.
DESC
task :stop_mongrel_cluster , :roles => :app do
sudo “monit stop all -g #{monit_group}”
end

9. from your local machine within your rails project root type: cap production setup, then cap production cold_deploy

10. Finally type: cap production long_deploy

11. your app should be deployed!

Getting RubyWorks on Ubuntu 7.04

Wednesday, November 21st, 2007
No Gravatar

Yesterday I wrote a post about getting rubyworks running on 7.10. Today I am going to run through the steps of getting it working on 7.04 (Feisty Fawn).

1. Install 7.04 with LAMP server ticked, this will amongst other things, get mysql server running.
N.B. do not call your user rails as rubyworks uses this user.

2. Reboot, and edit the /etc/apt/sources.list file. Remove the following line:
deb cdrom:[Ubuntu-Server 7.04 _Feisty Fawn_ - Release i386 (20070415)]/ feisty main restricted
This will stop apt-get installing packages from the cdrom, and look on the internet instead.

3. Now run sudo apt-get update to get the updated list of packages

4. Install openssh server so you can continue the rest of this guide remotely (from another computer) by typing: sudo apt-get install openssh-server

5. Find out the IP address of your server by typing ifconfig. If your connection is via ethernet, your ip address will probably be in the eth0 settings.

6. Go to your other computer and open up a terminal window (in windows download putty, on mac osx go to utilities, terminal in your finder. Connect to your ubuntu box by typing: ssh username_i_chose_on_ubuntu_install@my_ip_address_of_ubuntu_box

7. You are now ready to install rubyworks. Follow the guide here: http://rubyworks.rubyforge.org/installation/ubuntu.html
NB if you get an error on install of the type:

A package failed to install. Trying to recover:
Setting up rubyworks (1.0.0) …
Checking installation …
ls /etc/rails
haproxy.conf mongrel_3003.config mongrel_3005.config monit.pem
mongrel_3002.config mongrel_3004.config monit.conf
/usr/lib/ruby/1.8/fileutils.rb:1184:in `stat’: No such file or directory - /tmp/sources.rb (Errno::ENOENT)
from /usr/lib/ruby/1.8/fileutils.rb:1184:in `lstat’
from /usr/lib/ruby/1.8/fileutils.rb:1162:in `stat’
from /usr/lib/ruby/1.8/fileutils.rb:1244:in `copy_file’
from /usr/lib/ruby/1.8/fileutils.rb:459:in `copy_file’
from /usr/lib/ruby/1.8/fileutils.rb:383:in `cp’
from /usr/lib/ruby/1.8/fileutils.rb:1379:in `fu_each_src_dest’
from /usr/lib/ruby/1.8/fileutils.rb:1395:in `fu_each_src_dest0′
from /usr/lib/ruby/1.8/fileutils.rb:1377:in `fu_each_src_dest’
from /usr/lib/ruby/1.8/fileutils.rb:382:in `cp’
from /var/lib/dpkg/info/rubyworks.postinst:18
dpkg: error processing rubyworks (–configure):

type: sudo touch /tmp/sources.rb, and then run sudo aptitude install rubyworks again!

Thats your rubyworks stack running.

Next post wil be how to get capistrano deployments working on the stack.

Getting Rubyworks stack running on Ubuntu Gusty Gibbon 7.10

Tuesday, November 20th, 2007
No Gravatar

Rubyworks stack does not run entirely out of the box on Ubuntu Gusty Gibbon (7.10).

Here are a couple of things I did to get it working.

1. Following the readme for 7.04 on rubworks here: http://rubyworks.rubyforge.org/installation/ubuntu.html.

2. You get to

If all goes well, you now have a skeleton Rails application up and running at http://localhost:3001. There is also monitoring console running at http://localhost:2812. Congratulations!

and it probably won’t be running.

Solution: just run: sudo runsvdir-start

3. Then continue with the tutorial, make sure to change the port for the webserver from 3001 to 80. Tutorial is here: http://rubyworks.rubyforge.org/installation/ubuntu.html.

4. You need to configure your iptables to allow traffic into port 80 (and 2812 if you want to access monit from outside of localhost).
To do this you need to type this:

sudo iptables -A INPUT -p tcp --dport http -j ACCEPT
and
sudo iptables -A INPUT -p tcp --dport 2812 -j ACCEPT

Now try and connect to your machine from another!
N.B. opening 2812 for monit like this is a security risk, so follow the instructions on how to set up ssl etc if your server is on the internet

And that’s about it!

Using submit_tag to pass parameters

Thursday, January 25th, 2007
No Gravatar

If you want to pass a parameter through a form, you don’t pass it through submit_tag, you pass it in start_form_tag. For example, I want to pass the value of id:
<%= start_form_tag :action => ‘create’, :id => @thisparticularid %>

This is much more secure than using a hidden field, for obvious reasons!

Ruby on Rails - HABTM relationships

Wednesday, January 24th, 2007
No Gravatar

Using has_and_belongs_to_many is great if you want to manage simple HABTM assoctions, although it provides no access as far as I am aware to other attributes if present in the join table. For a more complex join, you’ve gotta code it by hand.
I came across a bug with HABTM today. Do not add an id field to the join table, if you do, the habtm join table id will be populated to contain the id of your joined model, rather than an auto-incremented number.
This inevitably leads to problems! Check out the habtm reference here for more info.


nogeek.org is Digg proof thanks to caching by WP Super Cache!