Posts Tagged ‘nginx’

How to configure a Ubuntu Slice for Merb + Datamapper

Sunday, July 20th, 2008
No Gravatar

This is a very rough and ready explanation of how to configure a slice for merb + datamapper.

This is for Ubuntu 7.10

- Add a user
adduser jason

- use visudo to add user to sudoers
visudo

- Stop remote root login
vi /etc/ssh/sshd_config
change PermitRootLogin to no

- Logout of root log back in a new user (jason)

- Update system
sudo apt-get update
sudo apt-get upgrade

- Build-essential
sudo apt-get install build-essential

- Git
sudo apt-get install git-core

- Ruby
sudo apt-get install ruby rdoc irb libyaml-ruby libzlib-ruby ri libopenssl-ruby

- Rubygems from source
Go to http://rubyforge.org/projects/rubygems/ to get the latest version
The new one is:
http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz
So I do:
wget http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz
tar xvf rubygems-1.2.0.tgz
cd rubygems-1.2.0
sudo ruby setup.rb
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
sudo apt-get install ruby1.8-dev
sudo gem update—system

- Gems

N.B. try and run the command below on a 256 slice on slicehost and you will run into resource allocation issues. I would recommend upgrading to 512, or waiting 5 days for the process to complete!
Alterantively type them in one by one

sudo gem install json json_pure erubis mime-types rspec hpricot mocha rubigen haml markaby mailfactory
sudo gem install rack

Lets install sake for the sake merb and dm tasks so we can stay on edge
sudo gem install sake
Does that bum out? In which case:
sudo gem install ParseTree—version 2.1.1
sudo gem install ruby2ruby—version 1.1.8

- Now we need to set up email using postfix
sudo apt-get install postfix
sudo dpkg-reconfigure postfix

- Sake tasks
sudo sake -i http://merbivore.com/merb-dev.sake
sudo sake -i http://datamapper.org/dm-dev.sake

sudo sake merb:clone
cd merb
sudo sake merb:install
sudo sake merb:install:plugins

If you want datamapper

Decide whether you are using mysql, postgres etc, i use mysql, so install mysql drivers:
install dependencies for data_objects:
sudo gem install addressable
sudo gem install english

sudo sake dm:clone
cd dm
sudo sake dm:install

- Mysql
sudo apt-get install mysql-server
Default socket for mysql rails
sudo ln -s /tmp/mysql.sock /var/run/mysqld/mysqld.sock

God monitoring
http://www.thewebfellas.com/blog/2008/2/12/a-simple-faith-monitoring-by-god

and the god init script for ubuntu
http://log.openmonkey.com/post/36103083/god-init-script-for-debian-ubuntu-systems

Very important don’t forget:
sudo apt-get install libmysqlclient15-dev

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!


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