Tag ∝ 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.
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.
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
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.
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
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
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.
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.
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!
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.
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