Hazelong.com

Malaysian Beauty Blog, Art, Geekery & more...

Tag ∝ capistrano

Deploying Rails to Centos : Capistrano

Thank you for following this series, this will be the last part of the series where we actually bring our development app to our remote server. Learning Rails has been a tremendous journey for me, the learning curve is not steep at all and it allows me to experiment and also to learn how to set up my own server to house it. Thanks to all the people that wrote tutorials and made railscasts out there I have learnt so much but this is just the beginning. This would not have been possible if I wasn’t introduced to the language itself by the_empty from webdevrefinery.

Deploying Rails to Centos 5

Right, before deploying with Capistrano we should make sure our application is fully prepared for deployment. The first thing we should do is strengthen our local’s .gitignore file. It should have the following lines :

log/*.log
*.log
tmp/**/*
tmp/*
doc/api
doc/app
config/database.yml.sample

Next, we should rename the database.yml file so that it doesn’t clash with other developer’s copy since they might differ from yours. Renaming it to database.yml.sample ensures that the production’s copy remain intact and the file doesnt clashes with other developers on your team. There is a great post by Simone Carletti about this issue that you should definitely check out.

You should also make sure that you have a root path pointing to some controller, meaning your index page should be properly routed and the public folder’s index.html is removed.

If you are on a shared host, you should mind your gems cuz they might upgrade their pack of gems without notifying you. To prevent anything from breaking you should unpack each gem to the vendor folder.

local $ cd vendor
local $ gem unpack money

To enable the gems to have version control, you just need to copy the contents of the lib folder to vendor

$ cp -R money-1.5.9/lib/* .
$ cp money-1.5.9/MIT-LICENSE LICENSE-money
$ rm -Rf money-1.5.9/
$ ls

Make sure you copy in the license depending on the gem’s license agreements.

In the future when you have upgraded your gems you can follow the same procedure again :

$ gem unpack money
Unpacked gem: 'money-1.7.1'
$ cp -Rf money-1.7.1/lib/* .
$ cp -f money-1.7.1/MIT-LICENSE LICENSE-money
$ rm -Rf money-1.7.1 

Remember to update your database.yml file to include your remote server’s database for the production database and make sure that it is using the mysql2 for the production database.

There are also some things you can tighten up when it comes to security. You can read more about it in this book. Important things to note are the following:

  • Never evaluate user input
  • Never evaluate SQL input

One last thing to check is to make sure you have eager associations for all your active records so that you can have the best optimal database performance.

If your remote server is using mySQL but your local machine is running SQLite for your app, you might also want a copy of the mySQL gem in your local machine.

gem install mysql2

Remember to include all this in the Gemfile

group :development, :test do
gem 'sqlite3-ruby', '1.2.5', :require => 'sqlite3'
end
group :production do
gem 'mysql2'
end

Run one last time after you are done.

 bundle install

When you are done, remember to push your changes up to the gitosis server.

 git commit -am "for deploy"
git push origin master

Alright. Capistrano. Yay!

First thing to do is to install Capistrano locally in your development machine. Capistrano only runs in the local machine and it uses SSH or SFTP to connect to your remote server. You do not need to install Capistrano in your remote server.

 local $ gem install capistrano

Check if it is working by doing :

 cap

If it shows you an error of not being able to find your Ruby Gems, then you need to install the <code>echoe</code> gem.

gem install echoe

Then you can see a list of capistrano tasks.

 cap -T

Now that it’s installed and working we can start. icon smile : Deploying Rails to Centos : Capistrano Finally. CD into your working directory.

 capify .

Remember the dot after capify.

This will create a <code>Capify</code> file in your working directory and a deploy.rb in your config folder. To deploy, we just need to ammed the deploy.rb file.

require 'bundler/capistrano'
set :application, "demoappname"
set :deploy_to,  "/home/#{application}"

server "yourdomain.com", :app, :web, :db, :primary => true

default_run_options[:ptr] = true # Ensure password prompt is prompt true
set :repository, 'git@yourdomain.com:demoappname.git' # your private/public url and user

set :scm, 'git' #scm utility name
set :branch, 'master' #remote branch to push
set :deploy_via, :copy # If you have public like github.com then use :remote_cache
set :user, 'root'
set :admin_runner, 'root'
#set :use_sudo, false #to avoid tty error

And also add the following lines for Passenger to work.

 namespace :deploy do
desc 'Restart Application'
task :restart, :roles => :app do
run "#{current_path}/tmp/restart.txt" #tells passenger to restart app
end
desc 'Start Application -- not needed for Passenger'
task :start, :roles => :app do
#empty since using passenger
end
end

Now you can prepare your server for deployment.

cap deploy:setup

You may need to enter your password and if you get a tty error just uncomment this line from yourdeploy.rb

set :use_sudo, false #to avoid tty error

If all goes well, your application directory in your remote server should have 2 new folders, releases and current Now, go back and edit your apache config file in your remote server in the VirtualHosts chunk section. This is your current chunk

DocumentRoot /home/demoapp/public

Change it to this and you should be all set to go after you restart your apache server. icon smile : Deploying Rails to Centos : Capistrano

DocumentRoot /home/demoapp/current/public

Check your deployment dependencies.

cap deploy:check

Ok. Time for deployment. For the first deployment, you can do this.

cap deploy:update

Now, errors may pop up now an then.. for my first deploy, I spent the whole night figuring out what I did wrong only to realize I forgot to push my app to gitosis first. lol.

Another error would be the bundle install error where they say that I changed my Gemfile without adding Gemfile.lock to git. Hmm. I couldn’t fix it but a fresh deploy on an empty folder fixed it. I cleared out my demo app and deleted the demoapp folder.

After that, ssh into your remote server and CD into your app’s directory.

rake RAILS_ENV=production db:schema:load

This will create all the nessecary tables for your application. The reason why the deployment is separated into this 2 steps, update and rake is to enable you to debug errors faster instead of doing one whole chunk of deploying to realize that the last step does not work and you have to redo the whole thing.

If you run into errors saying that you do not have mysql2 gem then you probably installed the wrong gem. It should be mysql2 gem not mysql gem, the mysql gem is now stale and no longer supported. You need to install this gem and also define it in Gemfile PLUS ensure that database.yml uses mysql2, not mysql.

If all goes well, all tables would be created, then you can run a test of whether anything works or not by doing

 rails console [production]
>> app.get("/")

If it returns 200 or 302 (or any other 2xx or 3xx code, or even 4xx if you haven’t configured the ”/” url for your application), you’re probably set. If it returns something in the 500’s, you’ll want to check your log/production.log and see why it blew up.

Next, try to access any static asset in your public folder by pointing your browser to http://yourdomain.com/javascripts/prototype.js
It should display the javascript file. If it doesn’t you probably have some issues with apache. Make sure your VirtualHosts is pointing to demoapp/current/public folder

When it works, it is time to start the magic.

 cap deploy:start

I need to cry now. Thanks for reading. Peace out.

After that, for every subsequent release you can just issue this command.

 cap deploy

Deploying Rails to Centos 5 : Gitosis

Why use GitHub when you can have your own? Hehe. Gitosis is a nice way of having your very own private repository. And it’s free! It just takes a while to set it up.

Deploying Rails to Centos 5

You should have Apache, mySQL, rails and Passenger installed by now. And of course, you will need to have Git installed as well. You could actually install Gitosis in another remote server but for me, Gitosis resides in the same remote server that I have been working in. To get Gitosis to work, you need to install Python as Gitosis is written in it.

 yum install python-setuptools

When you are done, get out to the root of your server and clone gitosis

git clone git://eagain.net/gitosis.git

Now go into the directory and run the installer.

cd gitostis
python setup.py install

When gitosis is installed you can safely delete the gitosis folder by running

 rm -rf gitosis

Now you need to set up a shell user to access Gitosis.

adduser --shell /bin/sh \
--group \
--disabled-password \
--home /home/git \
git

When you are done, you should have a /home/git folder ready for your repositories to reside in.

You already know that to git clone or push you have to roughly do a

git clone git@yourdomain.com:reponame.git

To have this setup you need to provide Gitosis your SSH key from your local computer.

So in your local computer’s terminal.

 local $ ssh-keygen -t rsa

However, if you already have an id_rsa.pub generated before you can actually skip this step and use your existing one instead.

Either way, once you have an id_rsa.pub file in your ~/.ssh folder run this command to copy it to your remote server

local $ scp $HOME/.ssh/id_rsa.pub user@111.111.111.111:/home/git

If you run into an error you can manually copy the text in id_rsa.pub file and make the exact same file in /home/git by

remote $ vim id_rsa.pub

Paste in the text you copied from your local file.

Once you are done, you are ready to initialize Gitosis.

remote $ su git
remote $ -H -u git gitosis-init < id_rsa.pub 

It should initialize and reinitialize a git repo. Now you can remove the id_rsa.pub in your remote computer.

Now do some permissions changing.

remote $
chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update
chmod 755 /home/git
chmod 700 /home/git/.ssh
chmod 644 /home/git/.ssh/authorized_keys

Back to your local computer’s terminal, head to an empty folder and clone the gitosis-admin files.

 local $ git clone git@yourdomain.com:gitosis-admin.git

If you couldn’t get past cuz of ssh or there is no git repo in that location. You need to change your local computer’s ssh config file.
Mine was in /private/etc/ssh_config. You can google to find the location of your ssh config file in your OS. Add this two lines in to make it automagically work

Host yourdomain.com
Port 1234

Replay with your remote server’s ServerName.com and the SSH port.

When you are able to clone, head into the local gitosis-admin directory either through terminal or by navigating there in Finder. Open up gitosis.conf and add the following lines:

[group reponame]
writable = reponame
members = copy-from-gitosis-admin-chunk-above

Back to your local terminal, you can now do some cool things to push the changes you did back to your remote server. Hehe.

local $ git commit -a -m "Allow my local have write access to remote"
git push

Now if you check your remote server’s gitosis.conf file you will be pleased to see that it is updated. icon smile : Deploying Rails to Centos 5 : Gitosis

The last thing to do here is to initialize a git setup in your local development app.

git init
git remote add origin git@yourdomain.com:reponame.git
git add . # add whole project
git commit -m "Initial code for myblog"
git push origin master:refs/heads/master

With this you will have your latest branch of your development app pushed to your very own Gitosis server, ready to deploy with Capistrano.

Note : If you want to be able to push from your remote app back to your Gitosis, you can generate the id_rsa.pub key from your remote server and place the file in the gitosis-admin/keydir directory. Update your gitosis.conf and you should have access to the project.

Next : Capistrano

Deploying Rails to Centos 5 : Passenger

Now that you have a proper rails and git stack in your remote server, it is time to get serious and start deploying. Because I have already set up the VirtualHosts for Passenger, I will be skipping that step. If you have missed that you might want to visit the Apache installing steps.

Deploying Rails to Centos 5

Before we install Passenger, let’s create a test application first. If you have made your directories already, check that it is /home/yourdomain.com/public

The path structure has to end in /public for Passenger to work.

Head to the directory root parent of yourdomain.com. In this case it should be

 cd /home

Delete the yourdomain.com folder for now. We will recreate it using Rails.

 rm -rf yourdomain.com

Now run the rails generator

 rails new yourdomain.com -d mysql

This tells rails to create an application using mySQL as the database.

cd yourdomain.com

Head into your rails application and edit the /config/database.yml file.

vim /config/database.yml

Scroll using your keyboard arrows to the production database and hit I to enter the credentials that you have created when you installed mySQL .

Now, install the mysql2 gem for this app.

sudo gem install mysql -- --with-mysql-config=/usr/bin/mysql_config

Ok now, to test if you can edit the application blindly without GUI. lol. Make some controllers, delete the public folder’s index.html Edit some routes and let it sit. For me, I just made a static controller with some static pages and a route to one of them. I also added some links here and there. A simple test app to check if everything is running fine when we install passenger.

When you are done, head to the root directory, domain.com folder and initialize git.

 git init

Now we can install Passenger.

gem install passenger

If you run into any missing dependencies just yum install them.

Passenger should install without a glitch. Next, we should install the module for passenger to work with Apache.

passenger-install-apache2-module

Halfway through, you will be asked to put some lines into your apache’s config file. Copy them. When it is done installing it will also ask you to put in the VirtualHost chunk of code, which we do not have to do since you already specified them when you install Apache earlier on the series. But if you haven’t, you can do so as well.

First let’s put in the LoadModules’ lines into apache’s config file.

vim /etc/httpd/conf/httpd.conf

If this is not the location that the config file resides in you can run a

 locate httpd.conf

to get the proper path.

Once you are in the file, scroll down to the chunk of LoadModules lines and paste in the Passenger’s LoadModules’ lines at the very end of the chunk. Finally scroll down all the way to your VirtualHosts chunk and make sure nothing is amiss.

Now, just restart your apache by running

httpd -k restart

Go to the domain in your browser and you should see your test app up and running. If you are greeted by Rails 404 page and you couldn’t figure out what is wrong with your application, you can head into /home/yourdomain.com/log/production.log to see the errors that is causing this problem.

Fix it and restart your apache. You should have your rails app up and ready to be replaced by your development app in your local server.

To push your app to the server using git you need a remote repository. In this case, you can set it up by installing Gitosis.
The workflow looks like this.
Local development app –push to–> Gitosis remote repo –used by Capistrano to deploy to–> Remote development app

Also, in dire times you might fix your remote app and you could do this:

Remote development app (changed) –push to –> Gitosis remote repo –fetched by–> Local development app

Deploying Rails to Centos 5 : Ruby, Gems & Rails

Hi there, if you have been following this series you would roughly know that I am trying to setup a remote Centos server to house my rails apps. After installing Apache, mySQL and Git, we are now ready to install Ruby, RubyGems & Rails.

Deploying Rails to Centos 5

As I like to have multiple versions of Ruby in my system, I am going to install RVM to handle them. But before all that, we should check if ruby already exists. SSH into your remote server and run

 ruby -v

If terminal shoots you back with a Ruby version number you already have Ruby installed and you should move on to installing rails.

Let’s install RVM by running this:

$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)

When you are done installing, you should edit your .bash_profile To do just that,

 vim ~/.bash_profile

Hit I to edit the file and paste in the following:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session.

Now, hit ESC to exit editing mode and SHIFT+Z twice to get out of vim. After this, you should log out of ssh and then log back in again to refresh the session.

When you are back in again, run this

type rvm | head -1

and they should reply with this:

 rvm is a function

If it doesn’t it means that the .bash_profile isn’t updated yet.

 rvm notes

Run this to see if you missed any dependencies for installing ruby. The missing dependencies should be listed out for you. Just follow the instructions before proceeding.

Now you can finally install Ruby,

rvm get head
rvm reload
rvm install 1.8.7
rvm install 1.9.2

Create a separate gemset for all your ruby versions by running:

rvm --create 1.8.7
rvm --create use 1.9.2

And make one of them your default by typing

rvm --default use 1.9

You can also check if ruby is installed by running

 ruby -v

They should be using your default version that you just set.

The good thing about installing RVM is that they automatically include RubyGems for you already. To check this fact,

 which gem
/Users/mhartl/.rvm/rubies/ruby-head/bin/gem

Now you can install Rails!

gem install rails --version 3.0.6

Check if it is installed by running

 rails -v

Now you can has rails. Woot.
Next, we will set up a test application for rails to try and make it work with Passenger.

Deploying Rails to Centos 5 : Git

Welcome to the rails deployment series. Today, we will be installing Git on your remote server. I am not going to go into the debate of SVN vs Git. *yawnz. The purpose of installing Git in the remote server is mainly cuz my local runs Git as well and I will also be installing Gitosis in the remote server to act as a repo where I can push changes to.

Deploying Rails to Centos 5

So to start off, make sure you have all the dependencies by installing

 yum install curl-devel expat-devel gettext-devel \
openssl-devel zlib-devel

Head to http://git-scm.com/download and grab the latest link for Linux. The link is at the top right sidebar. Took me a while to find it. darn. lol.

 wget paste-link-for-git

Once it is downloaded, you can install it by running

tar -jxf git-1.7.2.2.tar.bz
cd git-1.7.2.2
make prefix=/usr/local all
sudo make prefix=/usr/local install

Make sure you type in your git archive’s name, and not the one in the code above. icon biggrin : Deploying Rails to Centos 5 : Git

When the installation is done, you can now safely remove the tar files and the git-1.7.2.2 folder by doing

 rm git-1.7.2.2.tar.gz
rm -rf git-1.7.2.2

Once you are done installing, you can check if you have git install by running

 git

You are done for now! Leave git alone and let’s install some rubies and rails!

Deploying Rails to Centos 5 : mySQL

Hello, this is part two of the series!

If you have played with Rails before, you would know that the default database is SQLite. That is fine for development, for production having mySQL is better for handling more queries.

Deploying Rails to Centos 5

Make sure you have Apache installed before doing this. There are a few dependencies that you should install as well. Connect via ssh to your remote server and run this command

 yum install httpd-devel\
openssl-devel\
zlib-devel\
gcc\
gcc-c++\
curl-devel\
expat-devel\
gettext-devel\
mysql-server\
mysql-devel

Once you are done, you can boot up mysql by doing this

 service mysqld start

And also make sure that mySQL starts when you boot up your server.

chkconfig mysqld on

Now, let’s make sure that we have a database prepped for a test rails application. To do that, run

/usr/bin/mysql -u root -p

Enter your root password if there is any.

You should be greeted with a friendly :

 mysql> 

If you want to change your root password you can do so by running this,

UPDATE mysql.user SET Password = PASSWORD('password') WHERE User = 'root';
FLUSH PRIVILEGES;

Let’s create a database for our rails test application. icon biggrin : Deploying Rails to Centos 5 : mySQL

CREATE DATABASE demodb;

And add a user for this database.

 INSERT INTO mysql.user (User,Host,Password) VALUES('loginname','localhost',PASSWORD('yourpassword'));
GRANT ALL PRIVILEGES ON demodb.* to loginname@localhost;
FLUSH PRIVILEGES;

Now you have a working database! Yay!

For a list of handy commands to communicate with your mySQL database, head here.

Next : Git