Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
- name: Deploy new site release
user: deployer
hosts: all
- name: Fetch repo updates
git: >
dest="{{ git_cache_path }}"
- name: Get release timestamp
command: date +%Y%m%d%H%M%S
register: timestamp
- name: Name release directory
command: echo "{{ releases_dir }}/{{ timestamp.stdout }}"
register: release_path
- name: Create release directory
file: >
path={{ release_path.stdout }}
- name: Cop release
command: rsync -avz -avz --exclude-from '{{ git_cache_path }}/.slugignore' {{ git_cache_path }}/ {{ release_path.stdout }}
- name: Update app version
file: >
src={{ release_path.stdout }}
- name: Link uploads folder
path="{{ release_path.stdout }}/app/assets/uploads"
src={{ uploads_dir }}
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
# general config
set :application, "myapp"
set :valid_environments, ["staging","production"]
set :user, "deployer"
# git config
set :scm, :git
set :repository, ""
set :branch, "master"
set :deploy_via, :remote_cache
default_run_options[:pty] = true
# set :use_sudo, true
# ssh_options[:forward_agent] = true
set :current_dir, "myapp"
namespace :deploy do
desc "Sets up basic directory structure on target server"
task :setup, :except => { :no_release => true } do
dirs = [deploy_to, releases_path, shared_path]
dirs += { |d| File.join(shared_path, d) }
run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
desc <<-DESC
Updates the symlink to the most recently deployed version. Capistrano works \
by putting each new release of your application in its own directory. When \
you deploy a new version, this task's job is to update the `current' symlink \
to point at the new version. You will rarely need to call this task \
directly; instead, use the `deploy' task (which performs a complete \
deploy, including `restart') or the 'update' task (which does everything \
except `restart').
task :create_symlink, :except => { :no_release => true } do
on_rollback do
if previous_release
run "rm -f #{current_path}; ln -s #{previous_release} #{current_path}; true"
logger.important "no previous release to rollback to, rollback of symlink skipped"
# delete the old and create a new symlink to the latest release
run "rm -f #{current_path} && ln -s #{latest_release} #{current_path}"
# delete the uploads directory out of the new codebase if it exists. then symlink the uploads directory to there.
# run "rm -rf #{latest_release}/app/assets/uploads && ln -s #{deploy_to}/shared/uploads #{latest_release}/app/assets/uploads"
run "ln -s #{deploy_to}/shared/uploads #{latest_release}/app/assets/uploads"
desc <<-DESC
Restarts your application.
By default, this will be invoked via sudo as the 'app' user. If
you are in an environment where you can't use sudo, set
the :use_sudo variable to false:
set :use_sudo, false
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{sudo} chown -R www-data:www-data /var/apps/myapp/shared/uploads/"
run "#{sudo} /etc/init.d/apache2 reload"
desc <<-DESC
[internal] Touches up the released code. This is called by update_code \
after the basic deploy finishes.
This task will make the release group-writable (if the :group_writable \
variable is set to true, which is the default). It will then change \
ownership of the release and the symlink that was created if the owners \
variable exists.
task :finalize_update, :except => { :no_release => true } do
# run "chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
run "#{sudo} chown -R #{owners} #{current_path}" if exists?("owners")
run "#{sudo} chown -R #{owners} #{latest_release}" if exists?("owners")

Project: Django site for which original deployment was scripted with Capistrano. Updating the site and using Ansible to wrangle the server configurations. Why not deploy with it too?

Observed that for similar "Capistrano style" deployments, Capistrano is typically much faster at executing a deployment.

I've noticed a similar discrepancy between Fabric and Capistrano and suspect it comes down to the model of executing discrete commands (Ansible and Fabric) vs. bundling shell commands (Capistrano). This is based on observed output of Capistrano and my understanding of how Ansible and Fabric execute commands, which I do not assert to be authoritative!

Using Capistrano v2.15.4 and Ansible 1.5.4. Ran from my computer over my home network with Verizon FiOS. Target server is a small testing server on Rackspace:

Ansible total time: 1:50.44 total (43.821 total from a Digital Ocean instance) Capistrano total time: 16.951 total

The Ansible deployment playbook was written to try to follow the Capistrano steps as closely as possible (difference in using rsync vs. Capistrano's cp, however).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment