Deploy Ruby on Rails project on EC2 - ruby-on-rails

I have setup everything and i am able to connect to the server via ssh on a free tier
now my project is how can i upload the server files and database?
I see that there are some gems in rails such as rubber that deploy the files to a server but how can i also integrate git so i can commit changes as well?

Code
For uploading the files, check out capistrano. Another popular tool is Vlad the deployer.
Here's a simple deploy.rb for a rails3 app (assuming passenger) that only needs one server right now (replace all the with actual values):
require 'bundler/capistrano'
require 'capistrano_colors'
set :application, "<APP_NAME>"
set :repository, "git#github.com:<USER>/<PROJECT>.git"
set :branch, "master"
set :deploy_to, "/home/<DEPLOY_USER>/<APP_NAME>"
set :keep_releases, 3
set :scm, :git
set :user, "<DEPLOY_USER>"
set :use_sudo, false
set :deploy_via, :remote_cache
default_run_options[:pty] = true
default_run_options[:shell] = '/bin/bash -l'
ssh_options[:forward_agent] = true
role :web, "<IP_OR_PUBLIC_DNS>"
role :app, "<IP_OR_PUBLIC_DNS>"
namespace :deploy do
task :start do ; end
task :stop do ; end
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
end
after "deploy", "deploy:cleanup"
Note: you should ssh-add the private keys for the deploy user as well as the key you use for github before running cap deploy. (e.g. ssh-add ~/.ssh/id_dsa)
Database
In terms of the database, you can run migrations as part of a deploy via cap deploy:migrations, or independently via cap deploy:migrate. Just be sure to list a server with role :db
role :db, "<IP_OR_PUBLIC_DNS>", :primary => true
(Note: this is the server that will be used to run the migrations, not the actual db. The db should be specified in your database.yml).
Setting up the database itself is beyond the scope of this answer, but you can either run a db directly on the instance, or take a look at Amazon's RDS, which is really simple to set up and more stable than a db running on a single instance.

Related

Is there a way to tell Capistrano to deploy a Local Repository to a Remote Server?

I'm having a bit trouble while using capistrano, What I need to do is deploy from a Repository which resides in my local machine to my private VPS
So far my deploy.rb file looks like this:
set :application, "store"
set :repository, "/home/jose/linode/store"
#set :local_repository, "/home/jose/linode/store"
set :branch, "master"
set :scm, :git
set :user, "root"
set :scm_username, "my_git_user"
set :use_sudo, false
set :deploy_to, '/home/www/store'
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
role :web, "169.255.255.255" # Your HTTP server, Apache/etc
role :app, "169.255.255.255" # This may be the same as your `Web` server
role :db, "169.255.255.255", :primary => true # This is where Rails migrations will run
#role :db, "your slave db-server here"
However, this is failing, it's outputting the following error:
**** [169.255.255.255 :: err] fatal: repository '/home/jose/linode/store' does not exist**
This leads me to believe that it's looking for the repository in the remote server!
What configuration is needed to tell Capistrano that the Repo is located right here, not on: 169.255.255.255?
Many thanks in advance!
The setting that you are looking for is:
set :deploy_via, :copy
That creates a local .tar.gz file in your /tmp/ directory and pushes that to the server during deployment.
If you look at the source code, specifically lib/capistrano/recipes/deploy/strategy/copy.rb, you'll see a large block of comments beginning with the following.
# This class implements the strategy for deployments which work
# by preparing the source code locally, compressing it, copying the
# file to each target host, and uncompressing it to the deployment
# directory.
This article was written for an older version, but it's still quite interesting and covers deployment options and optimizations.

Deploying a Rails App to Multiple Servers using Capistrano - Best Practices

I have a rails application that I need to deploy to 3 servers - machine1.com, machine2.com and machine3.com. I want to be able to deploy it to all machines at once and each machine individually. Can someone help me out with a skeleton Capistrano config file / recipe? Should it all be in deploy.rb or should I break it out in machine1.rb, etc?
I thought I was on the right track getting Capistrano to take in command line arguments, but it choked when I tried set the roles within the namespaces. I'd pass in 'hosts=1,2,3' as an argument and set the role:app/web/db to "machine#{host}.com" after splitting on the command and going into an each do |host| {}...
Anyway, other than creating 4 different deploy.rb files and renaming it before running cap:deploy each time, I'm stumped. I'd like to be able to do the following:
cap deploy:machine1:latest_version_from_svn
cap deploy:all_machines:latest:version_from_svn
Just don't know if it should all be in deploy.rb split up with namespaces or if it should be broken into multiple *deploy**.rb files.
It should all go in one file. Here's an example:
set :application, "my-app"
set :repository, "git#git.my-git-host.com:my-app.git"
set :keep_releases, 5
set :deploy_via, :remote_cache
set :git_enable_submodules, true
set :scm, :git
set :user, 'your-user-here'
set :deploy_to, "/var/www/staging.mydomain.com"
set :branch, 'staging'
set :rails_env, 'staging'
role :web, "machine1.mydomain.com", "machine2.mydomain.com", "machine3.mydomain.com"
role :app, "machine1.mydomain.com", "machine2.mydomain.com", "machine3.mydomain.com"
role :db, "db.mydomain.com"
# ...
You'll see that only one db server was specified. This is the machine the migrations will be run from. If you only have one database (99.9% chance of the answer to that question being YES), then make sure to only provide one.
I had to use a slightly different syntax.
role :app, %w{s01.foobaz.com s02.foobaz.com}, user: 'deployer'
role :web, %w{s01.foobaz.com s02.foobaz.com}, user: 'deployer'

Rails, Slicehost, Capistrano - Deployment port issues

I'm getting a port error when I try to deploy my app via:
cap deploy:cold
The error:
ssh: connect to host domain.com port 22: Connection refused
My deploy.rb (replaced sensitive info where appropriate):
set :user, 'user'
set :domain, 'domain.com'
set :application, "App Name"
# file paths
set :repository, "user#domain.com:git/appname.git"
set :port, 9728
set :deploy_to, "/home/ruby/public_html/appname"
# distribute your applications across servers (the instructions below put them)
# all on the same server, definied above as 'domain', adjust as necessary
role :web, domain
role :app, domain
role :db, domain, :primary => true
# you might need to set this if you aren't seeing password prompts
# default_run_options[:pty] = true
# As Capistrano executes in a non-interactive mode and therefore doesn't cause
# any of your shell profile scripts to be run, the following might be needed
# if (for example) you have locally installed gems or applications. Note:
# this needs to contain the full values for the variables set, not simply
# the deltas.
# miscellaneous options
set :deploy_via, :remote_cache
set :scm, :git
set :branch, 'master'
set :scm_verbose, true
set :use_sudo, false
# task which causes Passenger to initiate a restart
namespace :deploy do
task :restart do
run "touch #{current_path}/tmp/restart.txt"
end
end
# optional task to reconfigure databases
after "deploy:update_code", :configure_database
desc "copy database.yml into the current release path"
task :configure_database, :roles => :app do
do_config = "#{deploy_to}/config/database.yml"
run "cp #{db_config} #{release_path}/config/database.yml"
end
I understand the error, but can't see where to make the change. I figured :set port, would handle it.
Have you tried putting the port in your repository path ? Something like ssh://user#domain.com:9728/git/appname.git
I think Capistrano only uses the port you specify in set :port to log in your remote servers.
Here's what works: you must have
set :port, port#
set :repository, "ssh://#{user}#IPAddress:#{port}/~/path/to/git
Or also try:
Here's a possible fix. add ssh_options[:port] = port# May work
Sorry to state the obvious, but:
Is the port actually open on the server?
Have you changed it to something else?
Is it accessible from the outside?
Is your firewall blocking it?
please try it
server "domain:9728", :web, :app, :db

Capistrano + Git + DreamHost

I'm trying to deploy my rails application by using Passenger and Capistrano on Dreamhost. I'm using Git as a version control and we bought an account from GitHub.
I have installed all required gems, Passenger and Capistrano in my local machine and I have cloned the repository of my project from GitHub in my local machine as wel.
According to Dreamhost support, they have Passenger, Ruby, Rails and etc on their server as well.
I'm currently following this article http://github.com/guides/deploying-with-capistrano for my deployment.
The following is my deploy.rb.
default_run_options[:pty] = true
ssh_options[:forward_agent] = true
# be sure to change these
set :user, 'gituser'
set :domain, 'github.com'
set :application, 'MyProjectOnGit'
#git#github.com:MyProjectOnGit.git
# the rest should be good
set :repository, "git#github.com:MyProjectOnGit.git"
set :deploy_to, "/ruby.michaelsync.net/"
set :deploy_via, :remote_cache
set :scm, 'git'
set :branch, 'master'
set :git_shallow_clone, 1
set :scm_verbose, true
set :use_sudo, false
set :git_enable_submodules, 1
server domain, :app, :web
role :db, domain, :primary => true
set :ssh_options, { :forward_agent => true }
namespace :deploy do
task :restart do
run "touch #{current_path}/tmp/restart.txt"
end
end
When I run "cap deploy", I'm getting the error below.
[deploy:update_code] exception while rolling back: Capistrano::ConnectionError, connection failed for: github.com (Net::SSH::AuthenticationFailed: gituser) connection failed for: github.com (Net::SSH::AuthenticationFailed: gituser)
Thanks in advance..
don't worry, you'll get it working in the end, I used to use the very same setup as yourself.... i.e. Dreamhost/Passenger/Capistrano/Git (and at one time, SVN) - it can be quite frustrating
Some things for you to do:
1) Read the following two articles by John Nunemaker # railstips.com - I used to refer to them every single time I had to setup a server on Dreamhost (the second one is the most important but the first link gives you some tips that are well worth following)
1.1) http://railstips.org/blog/archives/2008/11/23/gitn-your-shared-host-on/
1.2) http://railstips.org/blog/archives/2008/12/14/deploying-rails-on-dreamhost-with-passenger/
2) I think github is complaining about "gituser" - you do appear to set your username to "gituser" in your capfile - i would change that to your own name
3) you've got your domain down as github.com - again, this should be your own domain name and not github.... From what I recall..
4) start using heroku
good luck - hope this helps, let us know if it does or not....
cheers
You use your private url to clone your repository. Try with public clone URL
git://github.com/Myproject.git
i did to do sudo ln -s /opt/ruby/bin/packet_worker_runner /usr/bin/packet_worker_runner” and it solved the problem..
Thanks.

Fastest way to deploy rails apps with Passenger

I am working on a Dreamhost server with Rails 2.3.5.
Every time I make changes to a site, I have to ssh into the site, remove all the files, upload a zip file containing all the new files for the site, unzip that file, migrate the database, and go.
Something tells me there's a faster way to deploy rails apps. I am using mac Time Machine to keep track of different versions of my applications. I know git tracks files, but I don't really know how to work with it to deploy my applications, since passenger takes care of all the magic for me.
What would be a faster way to deploy my applications (and avoid the downtime associated with my method when I delete all files on the server)?
Thanks!
Take a look at Capistrano.
And go get yourself Capistrano helpers: http://github.com/westarete/capistrano-helpers
Here's a simplified, annotated Deploy file for my own site.
require 'capistrano-helpers/branch' # prompts for branch
require 'capistrano-helpers/passenger' # Support for Apache passenger
require 'capistrano-helpers/version' # Record the version number after deploying
require 'capistrano-helpers/privates' # handle sensitive files
require 'capistrano-helpers/shared'
set :application, "site"
set :repository, "file://."
set :scm, "git"
set :branch, "rails3"
set :deploy_via, :copy
set :copy_exclude, [ ".git", "assets", "test", "Capfile", "vishvish.tmproj", "bin" ]
set :deploy_to, "/blah/blah.com/#{application}"
set :user, "blah"
set :domain, "blah.com"
#Things you want symlinked afterwards, not in version control.
set :privates, %w{
config/database.yml
}
#Things you want shared across deployments, not uploaded every time.
set :shared, %w{
uploads
}
role :app, domain
role :web, domain
role :db, domain, :primary => true
namespace :deploy do
desc "Restarting mod_rails with restart.txt"
task :restart, :roles => :app, :except => { :no_release => true } do
run "touch #{current_path}/tmp/restart.txt"
end
[:start, :stop].each do |t|
desc "#{t} task is a no-op with mod_rails"
task t, :roles => :app do ; end
end
end
You definitely need git and capistrano.
My deployment process:
git commit
git push
cap deploy
Git is pretty straight forward. There are a ton of resources and how-tos on github.com.
If you aren't using source control you absolutely MUST fix that ...

Resources