Giới thiệu và cách sử dụng Capistrano

Như các bạn biết thì lâu nay việc deploy code các bạn thường remote lên server rồi sau dó pull code về cách này khá là thử công, việc quản lý một dự án thì không sao chứ các chục dự án mà nhó các thông số ip server, thư mục của dự án… đều đó thật là làm lãng phí thời gian của ngưòi quản lý dự án đó, chính vì vậy có nhiều tool auto deploy đã xuất hiện, chúng tôi không thể không nhắc đến Capistrano

Trong bài viết này chúng tôi sẽ review nó và hướng dẫn các bạn cách dùng nó, ngoài ra chúng tôi sẽ trình bày nó tại meetup Saigon Developer Group vào thứ 2 tuần sau, các bạn có rãnh ghé qua xem, chi tiết tại đây http://www.meetup.com/Engineers-Saigon/events/226296433

Capistrano Là Gì?

Capistrano là một chương trình được viết bằng Ruby cung cấp cho bạn một bộ công cụ tiên tiến để triển khai các ứng dụng web đến các máy chủ của bạn một cách tự động.

Mục tiêu cuối cùng của nó là trong mỗi một dự án sau khi có một tính nănng được relase trên git hoăc svn thì trên server(devel, staging, production) cũng có tính năng đó, chỉ với duy nhất một lệnh là các tính năng đó có trên bất kỳ môi trường phát triển nào(devel, staging, production)

cap deploy production

Các Tính Năng Của Capistrano

  • Triển khai ứng dụng web một cách chính xác cho bất kỳ số lượng máy chủ nào ta chỉ định theo tiến trình của hàng đợi do ta định nghĩa cho nó.
  • Tự động hóa lưu trữ logs của bất kỳ máy nào khi tương tác với nó chẵn hạn như kiểm tra số lần login, liệt kê bản cập nhật, fix các lỗi bảo mật.
  • Chạy các kịch bản script thông qua giao thức SSH
  • Thực hiện tự động hóa các task
  • Hỗ trợ các infrastructure(cơ sở hạ tầng) Chef-solo, Ánsible…
  • Hiển thị cũng như định dạng các dữ liệu đầu ra (progress, pretty, html, etc).
  • Dễ dàng tích hợp vói công cụ quản lý source như git
  • Hỗ trợ nhiều một trường phát triển
  • Hỗ trợ deploy lên bất ký máy chủ nào trong cùng một cụm máy chủ(subset)
  • Gửi thông tin sau khi deploy qua Slack hay Hipch

Capistrano là một công cụ kich bản rất mềm dẽo, nó có thể tích hợp bất kỳ phần mềm nào viết bằng Ruby do đó bạn có thể tái sử dụng nó trong các dự án
Ruby của bạn, nhưng bạn cũng có thể sử dụng cho bất kỳ dự án nào viết bằng java, php, etc

Cài Đặt Capistrano

Để cài đặt Capistrano thì bạn cần phải cài đặt các thành phần cơ bản như sau Ruby(>= 1.9.3), RubyGem. Bạn có thể cài đặt nó trực tiếp với Gem hoặc thông qua Bundle

Cài với Gem

$ gem install capistrano

hoặc

$ git clone https://github.com/capistrano/capistrano.git
$ cd capistrano
$ gem build *.gemspec
$ gem install *.gem

Cài thông qua Bundle

Cài đặt Bundle

$ gem install bundler

Thêm dòng bên dưới vào Gemfile:

gem 'capistrano', '~> 3.0.4'

Sau đó chạy lệnh:

$ bundle install

Chú ý rằng tham số 3.0.4 là không bắt buộc nhưng theo như trang chủ thì nó khuyên chúng ta nên thêm nó vào để cố định một vesion Capistrano để tránh những lỗi xuất hiện không mong muốn, những lỗi đó như thế nào bạn dùng rồi sẽ biết 🙂

Cấu Trúc

Capistrano sử dụng một hệ thống phân cấp thư mục được định nghĩa chặt chẽ trên mỗi máy chủ từ xa để tổ chức mã nguồn và dữ liệu triển khai liên quan khác. Các đường dẫn gốc của cấu trúc này có thể được định nghĩa với các biến cầu hình :deploy_to.

Giả sử cấu hình config/deploy.rb như sau:

set :deploy_to, '/var/www/my_app_name'

Sau đó, kiểm tra các thư mục bên trong thư mục /var/www/my_app_name sẽ như thế này:

├── current -> /var/www/my_app_name/releases/20150120114500/
├── releases
│   ├── 20150080072500
│   ├── 20150090083000
│   ├── 20150100093500
│   ├── 20150110104000
│   └── 20150120114500
├── repo
│   └── <VCS related data>
├── revisions.log
└── shared
└── <linked_files and linked_dirs>
  • current là một symlink chỉ tới phát hành mới nhất. Symlink này được cập nhật vào một triển khai thành công cuối cùng. Nếu triển khai không thành công trong bất kỳ bước nào các current symlink vẫn chỉ tới phát hành trước đó gần nhất.
  • releases chứa tất cả các triển khai trong một thư mục được đặt tên theo kiểu timestamped. Các current symlink sẽ trỏ tới những thư mục này.
  • repo chứa các phiên bản kiểm soát cấu hình hệ thống.
  • revisions.log được sử dụng để ghi lại từng triển khai hoặc rollback.
  • shared chứa linked_fileslinked_dirs được symlinked vào mỗi bản phát hành. Những thông tin này vẫn tồn tại qua việc triển khai và phát hành. Nó nên được sử dụng cho các tập tin tĩnh và cấu hình database…

Ứng dụng được chứa hoàn toàn bên trong đường dẫn cấu hình tại :deploy_to. Vì vậy, nếu bạn muốn triển khai nhiều ứng dụng trên cùng một server, rất đơn giản chỉ cần thay đổi cấu hình đường dẫn tại deploy_to.

Chú ý rằng bạn nên xem xét kỹ phần shared phần này khá là quan trọng, trong việc triển khai

Cấu Hình

Biến cấu hình có thể là global hoặc stage specific.

  • global
  • config/deploy.rb
  • stage specific
  • config/deploy/<stage_name>.rb

Truy cập

Mỗi biến có thể được gán một giá trị cụ thể:

set :application, 'MyLittleApplication'

# use a lambda to delay evaluation
set :application, -> { "SomeThing_#{fetch :other_config}" }

Một giá trị có thể được lấy từ cấu hình bất cứ lúc nào:

fetch :application
# => "MyLittleApplication"

fetch(:special_thing, 'some_default_value')
# will return the value if set, or the second argument as default value

Các biến số thông dụng

  • :application
  • Tên ứng dụng

  • :deploy_to

  • Mặc định:-> { “/var/www/#{fetch(:application)}” }
  • Đường dẫn trên máy chủ từ xa nơi lưu trữ ứng dụng được triển khai.
  • Nếu ứng dụng có chứa khoảng trắng hoặc đường dẫn không hợp lệ. Xem cấu trúc thư mục chính xác được sử dụng.

  • :scm

  • Mặc định: :git
  • Hệ thống quản lý mã nguồn được sử dụng.
  • Hiện tại hổ trợ: :git, :hg:svn. Các plugins có thể được bổ sung thêm.

  • :repo_url

  • URL to the repository
  • Must be a valid URL for the used SCM.

  • :repo_path

  • Mặc định: -> { “#{fetch(:deploy_to)}/repo” }
  • Đường dẫn vào các máy chủ từ xa, nơi các respository nên được đặt.
  • Điều này thường không cần phải được thiết lập.

  • :linked_files

  • Mặc định: []
  • Tập tin được liệt kê sẽ được symlinked vào mỗi thư mục phát hành trong thời gian triển khai.
  • Có thể sử dụng cho các tập tin cấu hình ít thay đổi như file cấu hình database.

  • :linked_dirs

  • Mặc định: []
  • Thư mục được liệt kê sẽ được symlinked vào mỗi thư mục phát hành trong thời gian triển khai.
  • Có thể sử dụng cho các thư mục ít thay đổi như uploads hoặc các dữ liệu khác.

  • :branch

  • Mặc định: master
  • Tên nhánh dự kiến triển khai từ SCM.

Bên cạnh những biến số trên, còn các biến số khác như: ::keep_releases, :tmp_dir, :local_user,…có thể tham khảo thêm tại đây

Chuẩn Bị Ứng Dụng Của Bạn

  1. Bạn cần phải có các SCM (git, Mercurial and SVN) trên server của bạn.
  2. Loại bỏ những tập tin, thư mục không cần thiết ra khỏi respository, chẳn hạn như các file cấu hình có chứa password.
  3. Cài đặt Capistrano cho ứng dụng của bạn.
$ cd my-project
$ cap install

hoặc

$ cd my-project
$ bundle exec cap install

Điều này sẽ tạo ra một loạt các tập tin:

├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
└── capistrano
└── tasks

Tạo các stages khác:

$ cap install STAGES=local,sandbox,qa,production

hoặc

$ bundle exec cap install STAGES=local,sandbox,qa,production

hoặc bạn có thể tạo một file <stage_name>.rb bên trong thư mục config/deploy và tiến hành cấu hình cho nó.

Các lệnh cần biết:

# list all available tasks
$ bundle exec cap -T

# check configuration of deploy to the staging environment
$ bundle exec cap staging deploy:check

# deploy to the staging environment
$ bundle exec cap staging deploy

# deploy to the production environment
$ bundle exec cap production deploy

# simulate deploying to the production environment
# does not actually do anything
$ bundle exec cap production deploy --dry-run

# list task dependencies
$ bundle exec cap production deploy --prereqs

# trace through task invocations
$ bundle exec cap production deploy --trace

Lưu ý: trên window, bạn nên cài phần mềm pageant hoặc tương tự để add tập tin ppk của máy bạn vào mới có thể sử dụng Capistrano. Còn trên Linux hoặc MacOS nếu như bạn có cài đạt trực tiếp capistrano thì lệnh

bundle exec cap thây bằng  cap

  1. Cấu hình địa chỉ server của bạn vào files được tạo

Xem ví dụ về config dưới đây về dự án của chúng tôi:

# role-based syntax
# ==================

# Defines a role with one or multiple servers. The primary server in each
# group is considered to be the first unless any  hosts have the primary
# property set. Specify the username and a domain or IP for the server.
# Don't use `:all`, it's a meta role.

# role :app, %w{deploy@example.com}, my_property: :my_value
role :web, %w{root@dev.phanbook.com}
server 'dev.phanbook.com', user: 'root', roles: %w{web}
set :deploy_to, '/usr/share/nginx/html/phanbook.devel'

# role :db,  %w{deploy@example.com}
  1. Thiết lập các thông tin chia sẻ trong deploy.rb

deploy.rb là nơi lưu trữ các thông tin cấu hình chung như:

  • Tên dự án
  • URL of respository
  • Tên nhánh được triển khai

Ví dụ:

# config valid only for current version of Capistrano
#lock '3.4.0'

set :application, 'phanbook'
set :repo_url, 'git@github.com:phanbook/phanbook.git'

# Default branch is :master
# ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp

# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, '/usr/share/nginx/html/phanbook.devel'
set :log_path,  '/var/log/phanbook'
# how many old releases do we want to keep
set :keep_releases, 5
# Default value for :scm is :git
set :scm, :git
set :branch,        'master'
  1. Cấu hình cho Slack
set :slack_webhook, -&gt; { 'https://hooks.slack.com/services/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' }
set :slack_icon_url,         -&gt; { 'http://gravatar.com/avatar/885e1c523b7975c4003de162d8ee8fee?r=g&amp;s=40' }
set :slack_icon_emoji,       -&gt; { ":)" } # will override icon_url, Must be a string (ex: ':shipit:')
#set :slack_channel,          -&gt; { '#general' }
set :slack_channel_starting, -&gt; { nil } # Channel to post to. Optional. Defaults to :slack_channel.
set :slack_channel_finished, -&gt; { nil } # Channel to post to. Optional. Defaults to :slack_channel.
set :slack_channel_failed,   -&gt; { nil } # Channel to post to. Optional. Defaults to :slack_channel.
#set :slack_username,         -&gt; { '@duythien' }
set :slack_run_starting,     -&gt; { true }
set :slack_run_finished,     -&gt; { true }
set :slack_run_failed,       -&gt; { true }
set :slack_msg_starting,     -&gt; { "#{ENV['USER'] || ENV['USERNAME']} has started deploying branch #{fetch :branch} of #{fetch :application} to #{fetch :server_name, 'production'} :rocket:" }
set :slack_msg_finished,     -&gt; { "#{ENV['USER'] || ENV['USERNAME']} has finished deploying branch #{fetch :branch} of #{fetch :application} to #{fetch :server_name, 'production'} :star2:" }
set :slack_msg_failed,       -&gt; { "#{ENV['USER'] || ENV['USERNAME']} failed to deploy branch #{fetch :branch} of #{fetch :application} to #{fetch :server_name, 'production'}" }
set :slack_title_starting,   -&gt; { nil }
set :slack_title_finished,   -&gt; { nil }
set :slack_title_failed,     -&gt; { nil }

Các bạn cần phải có quyền admin của Slack đó để tạo ra Webhook chanel mà bạn muốn gửi thông tin sau khi deploy, xem thêm tại dây https://github.com/phallstrom/slackistrano

Triển Khai Ứng Dụng Của Bạn Lên Remote Server

Như vậy là bạn đã hoàn thành các bước chuẩn bị để có thể triển khai ứng dụng lên remote server. Công việc tiếp theo của bạn là thực hiện thao tác cuối cùng để triển khải ứng dụng lên remote server một cách tự động.

Hãy thực hiện các bước sau:

  1. Kiểm tra các cấu hình của bạn
$ bundle exec cap development deploy:check

đây là kết quả sau khi chạy lệnh trên:

INFO [d1161d73] Running /usr/bin/env mkdir -p /tmp/phanbook/ as root@dev.phanbook.com
DEBUG [d1161d73] Command: /usr/bin/env mkdir -p /tmp/phanbook/
INFO [d1161d73] Finished in 359.805 seconds with exit status 0 (successful).
DEBUG Uploading /tmp/phanbook/git-ssh.sh 0.0%
INFO Uploading /tmp/phanbook/git-ssh.sh 100.0%
INFO [8e6f637b] Running /usr/bin/env chmod +x /tmp/phanbook/git-ssh.sh as root@dev.phanbook.com
DEBUG [8e6f637b] Command: /usr/bin/env chmod +x /tmp/phanbook/git-ssh.sh
INFO [8e6f637b] Finished in 0.930 seconds with exit status 0 (successful).
INFO [839d978d] Running /usr/bin/env git ls-remote --heads git@github.com:phanbook/phanbook.git as root@dev.phanbook.com
DEBUG [839d978d] Command: ( GIT_ASKPASS=/bin/echo GIT_SSH=/tmp/phanbook/git-ssh.sh /usr/bin/env git ls-remote --heads git@github.com:phanbook/phanbook.git )
DEBUG [839d978d]     Warning: Permanently added the RSA host key for IP address '192.30.252.130' to the list of known hosts.
DEBUG [839d978d]     188f3bb983100730d8a4ad36305d4f2eac19c04d    refs/heads/develop
DEBUG [839d978d]     1c373149e2f0d572aa9574ac70c98dce9db278fd    refs/heads/master
INFO [839d978d] Finished in 5.351 seconds with exit status 0 (successful).
INFO [b61f0961] Running /usr/bin/env mkdir -p /usr/share/nginx/html/phanbook.devel/shared /usr/share/nginx/html/phanbook.devel/releases as root@dev.phanbook.com
DEBUG [b61f0961] Command: /usr/bin/env mkdir -p /usr/share/nginx/html/phanbook.devel/shared /usr/share/nginx/html/phanbook.devel/releases
INFO [b61f0961] Finished in 0.607 seconds with exit status 0 (successful).
INFO [f838f366] Running /usr/bin/env mkdir -p /usr/share/nginx/html/phanbook.devel/shared/config as root@dev.phanbook.com
DEBUG [f838f366] Command: /usr/bin/env mkdir -p /usr/share/nginx/html/phanbook.devel/shared/config
INFO [f838f366] Finished in 0.983 seconds with exit status 0 (successful).
DEBUG [8f2f28aa] Running /usr/bin/env [ -f /usr/share/nginx/html/phanbook.devel/shared/config/config.php ] as root@dev.phanbook.com
DEBUG [8f2f28aa] Command: [ -f /usr/share/nginx/html/phanbook.devel/shared/config/config.php ]
DEBUG [8f2f28aa] Finished in 0.818 seconds with exit status 0 (successful).

Nếu có bất kì lỗi nào phát sinh bạn có thể fix ngay tại bước này. Như ở trên thi không có lỗi nào xảy ra 🙂

  1. Tiến hành triển khai ứng dụng lên remote server
$ bundle exec cap development deploy

Kết quả:

[...]
INFO [e5e254c2] Finished in 0.726 seconds with exit status 0 (successful).
INFO [15611e71] Running /usr/bin/env ln -s /usr/share/nginx/html/phanbook.devel/releases/20151104055621 /usr/share/nginx/html/phanbook.devel/releases/current as root@dev.phanbook.com
DEBUG [15611e71] Command: /usr/bin/env ln -s /usr/share/nginx/html/phanbook.devel/releases/20151104055621 /usr/share/nginx/html/phanbook.devel/releases/current
INFO [15611e71] Finished in 0.805 seconds with exit status 0 (successful).
INFO [a0828bd5] Running /usr/bin/env mv /usr/share/nginx/html/phanbook.devel/releases/current /usr/share/nginx/html/phanbook.devel as root@dev.phanbook.com
DEBUG [a0828bd5] Command: /usr/bin/env mv /usr/share/nginx/html/phanbook.devel/releases/current /usr/share/nginx/html/phanbook.devel
INFO [a0828bd5] Finished in 0.586 seconds with exit status 0 (successful).
DEBUG [723f5b9d] Running /usr/bin/env ls -xtr /usr/share/nginx/html/phanbook.devel/releases as root@dev.phanbook.com
DEBUG [723f5b9d] Command: /usr/bin/env ls -xtr /usr/share/nginx/html/phanbook.devel/releases
DEBUG [723f5b9d]     20151103101526    20151104055621
DEBUG [723f5b9d] Finished in 0.632 seconds with exit status 0 (successful).
DEBUG [05683786] Running /usr/bin/env if test ! -d /usr/share/nginx/html/phanbook.devel/releases; then echo "Directory does not exist '/usr/share/nginx/html/phanbook.devel/releases'" 1&gt;&amp;2; false; fi as root@dev.phanbook.com
DEBUG [05683786] Command: if test ! -d /usr/share/nginx/html/phanbook.devel/releases; then echo "Directory does not exist '/usr/share/nginx/html/phanbook.devel/releases'" 1&gt;&amp;2; false; fi
DEBUG [05683786] Finished in 0.634 seconds with exit status 0 (successful).
INFO [e931ce17] Running /usr/bin/env echo "Branch master (at 1c37314) deployed as release 20151104055621 by duythien" &gt;&gt; /usr/share/nginx/html/phanbook.devel/revisions.log as root@dev.phanbook.com
DEBUG [e931ce17] Command: echo "Branch master (at 1c37314) deployed as release 20151104055621 by duythien" &gt;&gt; /usr/share/nginx/html/phanbook.devel/revisions.log
INFO [e931ce17] Finished in 0.583 seconds with exit status 0 (successful).

Còn kết quả sau khi nhận được bên Slack như hình bên dưói đây

Slack capistrano

Chúc mừng bạn như vậy là bạn đã thành công triển khai ứng dụng lên remote server của bạn. Công việc còn lại là của bạn để cấu hình cho ứng dụng có thể chạy được trên server (cấu hình DocumentRoot,…)

Kết Luận

Capistrano là một công cụ khá hay và dễ sử dụng cũng như cấu hình những gì bạn muốn mà không cần phải lên server, nó giúp bạn dễ dàng triển khai một hoặc nhiều ứng dụng của bạn lên remote server.

Capistrano giúp bạn tiết kiệm nhiều thời gian cho quá trình triển khai ứng dụng. Toàn bộ mã nguồn demo capistrano chúng tôi để nó trên github bạn có thể lấy tại đây, bạn đã chuẩn bị triển khai cho dự án kế tiếp với Capistrano chưa, hãy chia sẽ những suy nghĩ cảu bạn về nó dưới đây:)

Author: Thiện Trần

Chỉ là một chàng trai code. Nếu bạn thích những gì tôi viết ở đây, hãy mua một tờ báo hoặc tờ vé số mà bạn gặp người bán dạo trên đường

Giới thiệu và cách sử dụng Capistrano
Rate this post