Sử dụng Capistrano 3 để deploy

Preface

Có nhiều phương pháp deploy ứng dụng lên server. Bạn có thể deploy bằng tay, hay sử dụng các tool tự động hoá như Capistrano, Chef, Ansible, Fabric, ...

Bài viết này hướng dẫn các bạn deploy một ứng dụng lên server sử dụng capistrano 3

Capistrano 3 là gì(?)

"A remote server automation and deployment tool written in Ruby."

Capistrano 3 viết bằng Ruby nhưng có thể sử dụng để deploy các ứng dụng được viết bằng bất cứ ngôn ngữ nào thông qua SSH.

Lợi ích của việc sử dụng Capistrano 3

Deploy thường tốn khá nhiều thời gian vì phụ thuộc vào rất nhiều điều kiện:

  • Các yếu tố cấu thành nên một ứng dụng (ngôn ngữ lập trình, framework, middleware, ...)
  • Môi trường và quy mô deploy
  • Thời hạn cho phép deploy
  • Giá thành

Đơn cử, bạn thử tưởng tượng ứng dụng của bạn cần được deploy lên 100 servers. Trong trường hợp thời gian deploy bị giới hạn, bạn có thể dùng tay để deploy (?)

Capistrano 3 giúp bạn triển khai ứng dụng đến nhiều server cùng một lúc chỉ bằng việc thực hiện trình tự các command đã được xây dựng sẵn theo kịch bản Capistrano cho phép bạn sao chép mã từ (SVN hoặc Git) đến nhiều server cùng 1 lúc thông qua SSH, và thực hiện chức năng trước và sau khi deploy như kiểm tra thông tin của file config, đổi tên tập tin, chạy di chuyển cơ sở dữ liệu, kiểm tra log ... một cách tự động hóa chỉ bằng việc thực hiện một số câu lệnh cap được chuẩn bị.

Mô hình Capistrano 3

Đầu tiên chúng ta cùng tìm hiểu các khái niệm thuật ngữ và mô hình cơ bản của capistrano 3:

Capistrano

Capistrano được cấu thành từ các thành phần sau:

  • Cap command
  • Capistrano library
  • Deploy task default (template)

Đầu tiên chúng ta sử dụng library và template default để viết ra file setting, sau đó chúng thực hiện chạy các file này bằng command cap. Từ đó trở đi chúng ta chỉ việc gọi các command cap này, ứng dụng sẽ được deploy hoặc thực hiện các câu lệnh monitor trên server một cách tự động hoá.

Library

  • Ruby Library
  • Capistrano extension

File setting

  • config/deploy.rb: chứa các thông tin và các task chung
  • config/deploy/[stage_name].rb: tên stage thực hiện deploy: production, staging, test...

Host

  • Local
  • Server

Dưới đây chúng ta sẽ lần lượt đi cài đặt và cấu hình file

Yêu cầu chuẩn bị trước

  1. Ruby programming basic để có thể viết được kịch bản (Task) thực hiện nhiệm vụ deploy
  2. Install:
  • rbenv
  • git
  • ruby
  • bundler
  1. Chuẩn bị server ảo để deploy lên:
  • Cài đặt vagrant
  • OS demo: Ubuntu 12.04 LTS
  • Thiết lập SSH
[email protected] ~/Documents> vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'hashicorp/precise32' is up to date...
==> default: VirtualBox VM is already running.
[email protected] ~/Documents> vagrant ssh
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686)

 * Documentation:  https://help.ubuntu.com/
New release '14.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
Welcome to your Vagrant-built virtual machine.
Last login: Fri Sep 14 06:22:31 2012 from 10.0.2.2
[email protected]:~$

Cài đặt capistrano 3

  • Câu lệnh install: sudo gem install capistrano
  • Kiểm tra version :cap -v
[email protected] ~/D/Cap3> cap -v
Capistrano Version: 3.4.0 (Rake Version: 10.4.2)
[email protected] ~/D/Cap3>

Sinh template cho file setting

Sinh ra template cho các file setting:

cap install [STAGES=stage_name1[,stage_name2,...]]

[email protected] ~/D/Cap3> cap install STAGES=local,staging,production

Các file template được sinh ra:

[email protected] ~/D/Cap3> tree
.
├── Capfile
├── config
│   ├── deploy
│   │   ├── local.rb
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
    └── capistrano
        └── tasks

5 directories, 5 files

Như đã nói qua về mô hình của capistrano 3 ở trên, bây giờ chúng ta lần lượt đi tìm hiểu và viết task cho các file config.

Viết file config/deploy/[stage_name].rb

Cụ thể trong demo này tôi sẽ viết file thực hiện deploy từ môi trường local, tên file là config/deploy/local.rb.

Cần thiết lập các thông tin sau ở file config/deploy/local.rb:

  • stage
  • host name
  • server role
  • login user
  • ssh
  • other
# coding: utf-8

# stage information
set :stage, :local

# servers information
server "127.0.0.1", user:'vagrant', roles: %w{app active}
# You can add more server here

# fetch(:default_env).merge!(rails_env: :web)

# project directory
set :deploy_to, "/var/www/july"

# app directory
set :app_dir, "july"

# log directory(Apache)
set :httpd_log, "/var/log/httpd/80"

Viết file config/deploy.rb

Là file cấu hình các thông tin chung của các stage:

  • Tên ứng dụng
  • Tên repository
  • SCM
  • Task
# coding: utf-8

set :application, "july"
set :repo_url, "[email protected]:LeThiNgoc/july.git"

# Default branch is :master
# ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call
set :branch, "master"

# Default deploy_to directory is /var/www/my_app
# set :deploy_to, '/var/www/my_app'

# Default value for :scm is :git
set :scm, :git

# Default value for :format is :pretty
# set :format, :pretty

# Default value for :log_level is :debug
set :log_level, :debug

# Default value for :pty is false
set :pty, true

# Default value for :linked_files is []
set :linked_files, %w{app/config/maintenance-ini.php}

# Default value for linked_dirs is []
set :linked_dirs, %w{app/storage/logs app/storage/cache app/storage/views app/storage/meta app/storage/sessions}

# Default value for default_env is {}
set :default_env, { path: "/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH" }

# Default value for keep_releases is 5
set :keep_releases, 5

# default ssh option
set :ssh_options, {
	keys: %w(~/.ssh/id_rsa),
	forward_agent: false,
	auth_methods: %w(publickey),
	user: "vagrant",
    port: 2222,
#	passphrase: nil
}

Viết task thực hiện deploy

lib/capistrano/tasks/deploy.rake định nghĩa task thực hiện kịch bản deploy:


# coding: utf-8

namespace :deploy do

	desc "check before execute"
	task :check_deploy do
		on release_roles :all do |host|
			begin
				# check conect
				execute :echo, "\"#{host}\""
			rescue
				# remove stand server from role
				unless fetch(:filter)
					set :filter, :roles => %w{active etc}
				end
			end
		end
	end
	before "deploy:check", :check_deploy

	desc "after finished pull"
	task :updated do
		invoke "deploy:permission"
	end

	desc "change permission"
	task :permission do
		next unless any? :linked_dirs
		next unless any? :linked_dirs
		on release_roles :all do
			execute :chmod, "777",  linked_dirs(shared_path)
		end
	end

	desc "create shared file"
	task :init_link do
		next unless any? :linked_files
		on release_roles :all do |host|
			linked_files(shared_path).each do |file|
				if !test "[ -e #{file} ]"
					# create shared file
					execute :touch, file
				end
			end
		end
	end
	before "deploy:check:linked_files", :init_link

	desc "check maintenance mode"
	task :maintenance do
		next unless any? :linked_files
		on release_roles :all do |host|
			fetch(:linked_files).each do |file|
				source = release_path.join(file)
				target = shared_path.join(file)
				original = "#{target}.org"
				unless test "[ -L #{target} ]"
					if test "[ -s #{target} ]"
						begin
							# check maintenance mode
							execute :grep, "-E", '"\\\\\"enabled\\\\\" => true"', target
						rescue
							# update if it is not maintenane mode
							execute :cp, source, target
						end
					else
						# if the file doesn't exist then copy it
						execute :cp, source, target
					end
					# source file
					execute :cp, source, original
				end
			end
		end
	end
	before "deploy:symlink:shared", :maintenance

	task "delete achived file after "
	task :after_rollback do
		on release_roles(:all) do
			# delete achived file after rollback
			archive_release = deploy_path.join("rolled-back-release-*.tar.gz")
			execute :rm, '-f', archive_release
		end
	end
	after "deploy:cleanup_rollback", :after_rollback
end

Deploy

  • Sử dụng command sau để deploy: cap [tên_stage] deploy
[email protected] ~/D/Cap3> cap local deploy
INFO [158fb16d] Running /usr/bin/env echo "127.0.0.1" as [email protected]
DEBUG [158fb16d] Command: /usr/bin/env echo "127.0.0.1"
DEBUG [158fb16d] 	127.0.0.1
INFO [158fb16d] Finished in 4.599 seconds with exit status 0 (successful).
INFO [4ae68589] Running /usr/bin/env mkdir -p /tmp/july/ as [email protected]
DEBUG [4ae68589] Command: /usr/bin/env mkdir -p /tmp/july/
INFO [4ae68589] Finished in 0.004 seconds with exit status 0 (successful).
DEBUG Uploading /tmp/july/git-ssh.sh 0.0%
INFO Uploading /tmp/july/git-ssh.sh 100.0%
INFO [c3e369b2] Running /usr/bin/env chmod +x /tmp/july/git-ssh.sh as [email protected]
DEBUG [c3e369b2] Command: /usr/bin/env chmod +x /tmp/july/git-ssh.sh
INFO [c3e369b2] Finished in 0.004 seconds with exit status 0 (successful).
INFO [eb36bfa6] Running /usr/bin/env git ls-remote --heads [email protected]:LeThiNgoc/july.git as [email protected]
DEBUG [eb36bfa6] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/july/git-ssh.sh /usr/bin/env git ls-remote --heads [email protected]:LeThiNgoc/july.git )
DEBUG [eb36bfa6] 	Warning: Permanently added the RSA host key for IP address '192.30.252.129' to the list of known hosts.
DEBUG [eb36bfa6]
DEBUG [eb36bfa6] 	6c9ecc4b9366bd440ebcc9453f031f1b600264f3
DEBUG [eb36bfa6]
DEBUG [eb36bfa6] 	refs/heads/master
DEBUG [eb36bfa6]
INFO [eb36bfa6] Finished in 3.507 seconds with exit status 0 (successful).
INFO [bb5a6897] Running /usr/bin/env mkdir -p /var/www/july/shared /var/www/july/releases as [email protected]
DEBUG [bb5a6897] Command: /usr/bin/env mkdir -p /var/www/july/shared /var/www/july/releases
INFO [bb5a6897] Finished in 0.005 seconds with exit status 0 (successful).
INFO [adc31a47] Running /usr/bin/env mkdir -p /var/www/july/shared/app/storage/logs /var/www/july/shared/app/storage/cache /var/www/july/shared/app/storage/views /var/www/july/shared/app/storage/meta /var/www/july/shared/app/storage/sessions as [email protected]
DEBUG [adc31a47] Command: /usr/bin/env mkdir -p /var/www/july/shared/app/storage/logs /var/www/july/shared/app/storage/cache /var/www/july/shared/app/storage/views /var/www/july/shared/app/storage/meta /var/www/july/shared/app/storage/sessions
INFO [adc31a47] Finished in 0.005 seconds with exit status 0 (successful).
INFO [00a63632] Running /usr/bin/env mkdir -p /var/www/july/shared/app/config as [email protected]
DEBUG [00a63632] Command: /usr/bin/env mkdir -p /var/www/july/shared/app/config
INFO [00a63632] Finished in 0.004 seconds with exit status 0 (successful).
DEBUG [dde727cb] Running /usr/bin/env [ -e /var/www/july/shared/app/config/maintenance-ini.php ] as [email protected]
DEBUG [dde727cb] Command: [ -e /var/www/july/shared/app/config/maintenance-ini.php ]
DEBUG [dde727cb] Finished in 0.003 seconds with exit status 1 (failed).
INFO [1511d589] Running /usr/bin/env touch /var/www/july/shared/app/config/maintenance-ini.php as [email protected]
DEBUG [1511d589] Command: /usr/bin/env touch /var/www/july/shared/app/config/maintenance-ini.php
INFO [1511d589] Finished in 0.005 seconds with exit status 0 (successful).
DEBUG [aac6edf7] Running /usr/bin/env [ -f /var/www/july/shared/app/config/maintenance-ini.php ] as [email protected]
DEBUG [aac6edf7] Command: [ -f /var/www/july/shared/app/config/maintenance-ini.php ]
DEBUG [aac6edf7] Finished in 0.003 seconds with exit status 0 (successful).
DEBUG [54bc5044] Running /usr/bin/env [ -f /var/www/july/current/REVISION ] as [email protected]
DEBUG [54bc5044] Command: [ -f /var/www/july/current/REVISION ]
DEBUG [54bc5044] Finished in 0.006 seconds with exit status 1 (failed).
DEBUG [3011d834] Running /usr/bin/env [ -f /var/www/july/repo/HEAD ] as [email protected]
DEBUG [3011d834] Command: [ -f /var/www/july/repo/HEAD ]
DEBUG [3011d834] Finished in 0.004 seconds with exit status 1 (failed).
DEBUG [3cdbdb4c] Running /usr/bin/env if test ! -d /var/www/july; then echo "Directory does not exist '/var/www/july'" 1>&2; false; fi as [email protected]
DEBUG [3cdbdb4c] Command: if test ! -d /var/www/july; then echo "Directory does not exist '/var/www/july'" 1>&2; false; fi
DEBUG [3cdbdb4c] Finished in 0.004 seconds with exit status 0 (successful).
INFO [be6a627f] Running /usr/bin/env git clone --mirror [email protected]:LeThiNgoc/july.git /var/www/july/repo as [email protected]
DEBUG [be6a627f] Command: cd /var/www/july && ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/july/git-ssh.sh /usr/bin/env git clone --mirror [email protected]:LeThiNgoc/july.git /var/www/july/repo )
DEBUG [be6a627f] 	Cloning into bare repository '/var/www/july/repo'...
DEBUG [be6a627f]
DEBUG [be6a627f] 	remote: Counting objects: 83, done.[K
DEBUG [be6a627f]
DEBUG [be6a627f] 	remote: Compressing objects:   1% (1/64)   [K
DEBUG [be6a627f] 	remote: Compressing objects:   3% (2/64)   [K
DEBUG [be6a627f] 	remote: Compressing objects:   4% (3/64)   [K
...
INFO [be6a627f] Finished in 4.409 seconds with exit status 0 (successful).
DEBUG [97464c83] Running /usr/bin/env if test ! -d /var/www/july/repo; then echo "Directory does not exist '/var/www/july/repo'" 1>&2; false; fi as [email protected]
DEBUG [97464c83] Command: if test ! -d /var/www/july/repo; then echo "Directory does not exist '/var/www/july/repo'" 1>&2; false; fi
DEBUG [97464c83] Finished in 0.003 seconds with exit status 0 (successful).
INFO [759e31e2] Running /usr/bin/env git remote update as [email protected]
DEBUG [759e31e2] Command: cd /var/www/july/repo && ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/july/git-ssh.sh /usr/bin/env git remote update )
DEBUG [759e31e2] 	Fetching origin
INFO [759e31e2] Finished in 3.658 seconds with exit status 0 (successful).
DEBUG [a0eb9699] Running /usr/bin/env if test ! -d /var/www/july/repo; then echo "Directory does not exist '/var/www/july/repo'" 1>&2; false; fi as [email protected]
DEBUG [a0eb9699] Command: if test ! -d /var/www/july/repo; then echo "Directory does not exist '/var/www/july/repo'" 1>&2; false; fi
DEBUG [a0eb9699] Finished in 0.004 seconds with exit status 0 (successful).
INFO [ac880ab5] Running /usr/bin/env mkdir -p /var/www/july/releases/20150728023458 as [email protected]
DEBUG [ac880ab5] Command: cd /var/www/july/repo && ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/july/git-ssh.sh /usr/bin/env mkdir -p /var/www/july/releases/20150728023458 )
INFO [ac880ab5] Finished in 0.004 seconds with exit status 0 (successful).
INFO [959992b1] Running /usr/bin/env git archive master | tar -x -f - -C /var/www/july/releases/20150728023458 as [email protected]
DEBUG [959992b1] Command: cd /var/www/july/repo && ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/july/git-ssh.sh /usr/bin/env git archive master | tar -x -f - -C /var/www/july/releases/20150728023458 )
INFO [959992b1] Finished in 0.009 seconds with exit status 0 (successful).
DEBUG [09c1b589] Running /usr/bin/env if test ! -d /var/www/july/repo; then echo "Directory does not exist '/var/www/july/repo'" 1>&2; false; fi as [email protected]
DEBUG [09c1b589] Command: if test ! -d /var/www/july/repo; then echo "Directory does not exist '/var/www/july/repo'" 1>&2; false; fi
DEBUG [09c1b589] Finished in 0.009 seconds with exit status 0 (successful).
DEBUG [1974f221] Running /usr/bin/env git rev-list --max-count=1 --abbrev-commit master as [email protected]
DEBUG [1974f221] Command: cd /var/www/july/repo && ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/july/git-ssh.sh /usr/bin/env git rev-list --max-count=1 --abbrev-commit master )
DEBUG [1974f221] 	6c9ecc4
DEBUG [1974f221]
DEBUG [1974f221] Finished in 0.007 seconds with exit status 0 (successful).
DEBUG [5e97e4bf] Running /usr/bin/env if test ! -d /var/www/july/releases/20150728023458; then echo "Directory does not exist '/var/www/july/releases/20150728023458'" 1>&2; false; fi as [email protected]
DEBUG [5e97e4bf] Command: if test ! -d /var/www/july/releases/20150728023458; then echo "Directory does not exist '/var/www/july/releases/20150728023458'" 1>&2; false; fi
DEBUG [5e97e4bf] Finished in 0.005 seconds with exit status 0 (successful).
INFO [09986b70] Running /usr/bin/env echo "6c9ecc4" >> REVISION as [email protected]
DEBUG [09986b70] Command: cd /var/www/july/releases/20150728023458 && /usr/bin/env echo "6c9ecc4" >> REVISION
INFO [09986b70] Finished in 0.011 seconds with exit status 0 (successful).
DEBUG [b64153a7] Running /usr/bin/env [ -L /var/www/july/shared/app/config/maintenance-ini.php ] as [email protected]
DEBUG [b64153a7] Command: [ -L /var/www/july/shared/app/config/maintenance-ini.php ]
DEBUG [b64153a7] Finished in 0.006 seconds with exit status 1 (failed).
DEBUG [5697cd57] Running /usr/bin/env [ -s /var/www/july/shared/app/config/maintenance-ini.php ] as [email protected]
DEBUG [5697cd57] Command: [ -s /var/www/july/shared/app/config/maintenance-ini.php ]
DEBUG [5697cd57] Finished in 0.005 seconds with exit status 1 (failed).
INFO [4e1054f2] Running /usr/bin/env cp /var/www/july/releases/20150728023458/app/config/maintenance-ini.php /var/www/july/shared/app/config/maintenance-ini.php as [email protected]
DEBUG [4e1054f2] Command: /usr/bin/env cp /var/www/july/releases/20150728023458/app/config/maintenance-ini.php /var/www/july/shared/app/config/maintenance-ini.php
INFO [4e1054f2] Finished in 0.006 seconds with exit status 0 (successful).
INFO [0f275757] Running /usr/bin/env cp /var/www/july/releases/20150728023458/app/config/maintenance-ini.php /var/www/july/shared/app/config/maintenance-ini.php.org as [email protected]
DEBUG [0f275757] Command: /usr/bin/env cp /var/www/july/releases/20150728023458/app/config/maintenance-ini.php /var/www/july/shared/app/config/maintenance-ini.php.org
INFO [0f275757] Finished in 0.005 seconds with exit status 0 (successful).
INFO [78af78f2] Running /usr/bin/env mkdir -p /var/www/july/releases/20150728023458/app/config as [email protected]
DEBUG [78af78f2] Command: /usr/bin/env mkdir -p /var/www/july/releases/20150728023458/app/config
INFO [78af78f2] Finished in 0.005 seconds with exit status 0 (successful).
DEBUG [e4ee925c] Running /usr/bin/env [ -L /var/www/july/releases/20150728023458/app/config/maintenance-ini.php ] as [email protected]
DEBUG [e4ee925c] Command: [ -L /var/www/july/releases/20150728023458/app/config/maintenance-ini.php ]
DEBUG [e4ee925c] Finished in 0.006 seconds with exit status 1 (failed).
DEBUG [9072b0ce] Running /usr/bin/env [ -f /var/www/july/releases/20150728023458/app/config/maintenance-ini.php ] as [email protected]
DEBUG [9072b0ce] Command: [ -f /var/www/july/releases/20150728023458/app/config/maintenance-ini.php ]
DEBUG [9072b0ce] Finished in 0.004 seconds with exit status 0 (successful).
INFO [2d628c64] Running /usr/bin/env rm /var/www/july/releases/20150728023458/app/config/maintenance-ini.php as [email protected]
DEBUG [2d628c64] Command: /usr/bin/env rm /var/www/july/releases/20150728023458/app/config/maintenance-ini.php
INFO [2d628c64] Finished in 0.005 seconds with exit status 0 (successful).
INFO [543bb5e3] Running /usr/bin/env ln -s /var/www/july/shared/app/config/maintenance-ini.php /var/www/july/releases/20150728023458/app/config/maintenance-ini.php as [email protected]
DEBUG [543bb5e3] Command: /usr/bin/env ln -s /var/www/july/shared/app/config/maintenance-ini.php /var/www/july/releases/20150728023458/app/config/maintenance-ini.php
INFO [543bb5e3] Finished in 0.009 seconds with exit status 0 (successful).
INFO [6cb8cd1b] Running /usr/bin/env mkdir -p /var/www/july/releases/20150728023458/app/storage /var/www/july/releases/20150728023458/app/storage /var/www/july/releases/20150728023458/app/storage /var/www/july/releases/20150728023458/app/storage /var/www/july/releases/20150728023458/app/storage as [email protected]
DEBUG [6cb8cd1b] Command: /usr/bin/env mkdir -p /var/www/july/releases/20150728023458/app/storage /var/www/july/releases/20150728023458/app/storage /var/www/july/releases/20150728023458/app/storage /var/www/july/releases/20150728023458/app/storage /var/www/july/releases/20150728023458/app/storage
INFO [6cb8cd1b] Finished in 0.005 seconds with exit status 0 (successful).
DEBUG [2d6c2341] Running /usr/bin/env [ -L /var/www/july/releases/20150728023458/app/storage/logs ] as [email protected]
DEBUG [2d6c2341] Command: [ -L /var/www/july/releases/20150728023458/app/storage/logs ]
DEBUG [2d6c2341] Finished in 0.003 seconds with exit status 1 (failed).
DEBUG [f3129564] Running /usr/bin/env [ -d /var/www/july/releases/20150728023458/app/storage/logs ] as [email protected]
DEBUG [f3129564] Command: [ -d /var/www/july/releases/20150728023458/app/storage/logs ]
DEBUG [f3129564] Finished in 0.003 seconds with exit status 0 (successful).
INFO [10cc746f] Running /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/logs as [email protected]
DEBUG [10cc746f] Command: /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/logs
INFO [10cc746f] Finished in 0.004 seconds with exit status 0 (successful).
INFO [e0bd1066] Running /usr/bin/env ln -s /var/www/july/shared/app/storage/logs /var/www/july/releases/20150728023458/app/storage/logs as [email protected]
DEBUG [e0bd1066] Command: /usr/bin/env ln -s /var/www/july/shared/app/storage/logs /var/www/july/releases/20150728023458/app/storage/logs
INFO [e0bd1066] Finished in 0.004 seconds with exit status 0 (successful).
DEBUG [7507d411] Running /usr/bin/env [ -L /var/www/july/releases/20150728023458/app/storage/cache ] as [email protected]
DEBUG [7507d411] Command: [ -L /var/www/july/releases/20150728023458/app/storage/cache ]
DEBUG [7507d411] Finished in 0.003 seconds with exit status 1 (failed).
DEBUG [5940188b] Running /usr/bin/env [ -d /var/www/july/releases/20150728023458/app/storage/cache ] as [email protected]
DEBUG [5940188b] Command: [ -d /var/www/july/releases/20150728023458/app/storage/cache ]
DEBUG [5940188b] Finished in 0.005 seconds with exit status 0 (successful).
INFO [808252d5] Running /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/cache as [email protected]
DEBUG [808252d5] Command: /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/cache
INFO [808252d5] Finished in 0.004 seconds with exit status 0 (successful).
INFO [4ef1f6a9] Running /usr/bin/env ln -s /var/www/july/shared/app/storage/cache /var/www/july/releases/20150728023458/app/storage/cache as [email protected]
DEBUG [4ef1f6a9] Command: /usr/bin/env ln -s /var/www/july/shared/app/storage/cache /var/www/july/releases/20150728023458/app/storage/cache
INFO [4ef1f6a9] Finished in 0.004 seconds with exit status 0 (successful).
DEBUG [1ceac512] Running /usr/bin/env [ -L /var/www/july/releases/20150728023458/app/storage/views ] as [email protected]
DEBUG [1ceac512] Command: [ -L /var/www/july/releases/20150728023458/app/storage/views ]
DEBUG [1ceac512] Finished in 0.008 seconds with exit status 1 (failed).
DEBUG [6ad33c88] Running /usr/bin/env [ -d /var/www/july/releases/20150728023458/app/storage/views ] as [email protected]
DEBUG [6ad33c88] Command: [ -d /var/www/july/releases/20150728023458/app/storage/views ]
DEBUG [6ad33c88] Finished in 0.005 seconds with exit status 0 (successful).
INFO [03a6bdb4] Running /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/views as [email protected]
DEBUG [03a6bdb4] Command: /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/views
INFO [03a6bdb4] Finished in 0.005 seconds with exit status 0 (successful).
INFO [93b02294] Running /usr/bin/env ln -s /var/www/july/shared/app/storage/views /var/www/july/releases/20150728023458/app/storage/views as [email protected]
DEBUG [93b02294] Command: /usr/bin/env ln -s /var/www/july/shared/app/storage/views /var/www/july/releases/20150728023458/app/storage/views
INFO [93b02294] Finished in 0.004 seconds with exit status 0 (successful).
DEBUG [e68132b2] Running /usr/bin/env [ -L /var/www/july/releases/20150728023458/app/storage/meta ] as [email protected]
DEBUG [e68132b2] Command: [ -L /var/www/july/releases/20150728023458/app/storage/meta ]
DEBUG [e68132b2] Finished in 0.004 seconds with exit status 1 (failed).
DEBUG [9ed377bd] Running /usr/bin/env [ -d /var/www/july/releases/20150728023458/app/storage/meta ] as [email protected]
DEBUG [9ed377bd] Command: [ -d /var/www/july/releases/20150728023458/app/storage/meta ]
DEBUG [9ed377bd] Finished in 0.003 seconds with exit status 0 (successful).
INFO [84ab330c] Running /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/meta as [email protected]
DEBUG [84ab330c] Command: /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/meta
INFO [84ab330c] Finished in 0.005 seconds with exit status 0 (successful).
INFO [2296fbe6] Running /usr/bin/env ln -s /var/www/july/shared/app/storage/meta /var/www/july/releases/20150728023458/app/storage/meta as [email protected]
DEBUG [2296fbe6] Command: /usr/bin/env ln -s /var/www/july/shared/app/storage/meta /var/www/july/releases/20150728023458/app/storage/meta
INFO [2296fbe6] Finished in 0.007 seconds with exit status 0 (successful).
DEBUG [5473fa16] Running /usr/bin/env [ -L /var/www/july/releases/20150728023458/app/storage/sessions ] as [email protected]
DEBUG [5473fa16] Command: [ -L /var/www/july/releases/20150728023458/app/storage/sessions ]
DEBUG [5473fa16] Finished in 0.003 seconds with exit status 1 (failed).
DEBUG [9518ce86] Running /usr/bin/env [ -d /var/www/july/releases/20150728023458/app/storage/sessions ] as [email protected]
DEBUG [9518ce86] Command: [ -d /var/www/july/releases/20150728023458/app/storage/sessions ]
DEBUG [9518ce86] Finished in 0.003 seconds with exit status 0 (successful).
INFO [aa0fa9d2] Running /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/sessions as [email protected]
DEBUG [aa0fa9d2] Command: /usr/bin/env rm -rf /var/www/july/releases/20150728023458/app/storage/sessions
INFO [aa0fa9d2] Finished in 0.006 seconds with exit status 0 (successful).
INFO [f930de48] Running /usr/bin/env ln -s /var/www/july/shared/app/storage/sessions /var/www/july/releases/20150728023458/app/storage/sessions as [email protected]
DEBUG [f930de48] Command: /usr/bin/env ln -s /var/www/july/shared/app/storage/sessions /var/www/july/releases/20150728023458/app/storage/sessions
INFO [f930de48] Finished in 0.008 seconds with exit status 0 (successful).
INFO [6b4eb814] Running /usr/bin/env chmod 777 /var/www/july/shared/app/storage/logs /var/www/july/shared/app/storage/cache /var/www/july/shared/app/storage/views /var/www/july/shared/app/storage/meta /var/www/july/shared/app/storage/sessions as [email protected]
DEBUG [6b4eb814] Command: /usr/bin/env chmod 777 /var/www/july/shared/app/storage/logs /var/www/july/shared/app/storage/cache /var/www/july/shared/app/storage/views /var/www/july/shared/app/storage/meta /var/www/july/shared/app/storage/sessions
INFO [6b4eb814] Finished in 0.005 seconds with exit status 0 (successful).
INFO [e740daab] Running /usr/bin/env ln -s /var/www/july/releases/20150728023458 /var/www/july/releases/current as [email protected]
DEBUG [e740daab] Command: /usr/bin/env ln -s /var/www/july/releases/20150728023458 /var/www/july/releases/current
INFO [e740daab] Finished in 0.009 seconds with exit status 0 (successful).
INFO [420691b1] Running /usr/bin/env mv /var/www/july/releases/current /var/www/july as [email protected]
DEBUG [420691b1] Command: /usr/bin/env mv /var/www/july/releases/current /var/www/july
INFO [420691b1] Finished in 0.004 seconds with exit status 0 (successful).
DEBUG [0e4ea69e] Running /usr/bin/env ls -xtr /var/www/july/releases as [email protected]
DEBUG [0e4ea69e] Command: /usr/bin/env ls -xtr /var/www/july/releases
DEBUG [0e4ea69e] 	20150728023458
DEBUG [0e4ea69e] Finished in 0.005 seconds with exit status 0 (successful).
DEBUG [e4c54d1a] Running /usr/bin/env if test ! -d /var/www/july/releases; then echo "Directory does not exist '/var/www/july/releases'" 1>&2; false; fi as [email protected]
DEBUG [e4c54d1a] Command: if test ! -d /var/www/july/releases; then echo "Directory does not exist '/var/www/july/releases'" 1>&2; false; fi
DEBUG [e4c54d1a] Finished in 0.005 seconds with exit status 0 (successful).
INFO [c8d0b5a1] Running /usr/bin/env echo "Branch master (at 6c9ecc4) deployed as release 20150728023458 by framgiavn" >> /var/www/july/revisions.log as [email protected]
DEBUG [c8d0b5a1] Command: echo "Branch master (at 6c9ecc4) deployed as release 20150728023458 by framgiavn" >> /var/www/july/revisions.log
INFO [c8d0b5a1] Finished in 0.004 seconds with exit status 0 (successful).

Lời kết

Trên đây là demo nhỏ về việc sử dụng capistrano 3 để deploy một ứng dụng. Ngoài ra chúng ta hoàn toàn có thể viết task để thao tác với server như start/stop maintenance, start/stop/restart apache, lấy log... (Chúng ta cùng tìm hiểu trong lần tiếp theo).

Link tham khảo

http://capistranorb.com/

https://www.digitalocean.com/community/tutorials/how-to-use-capistrano-to-automate-deployments-getting-started