Deploy Laravel với Capistrano

Nội dung chính

I. Giới thiệu Capistrano.

II. Chuẩn bị một project Laravel, install và cấu hình Capistrano

III. Thực hiện việc deploy

I. Giới thiệu Capistrano

1. Giới thiệu chung.

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.

Capistrano cho phép bạn sao chép mã từ (SVN hoặc Git) đến máy chủ thông qua SSH, và thực hiện chức năng trước và sau khi triển khai như khởi động lại một máy chủ web, bộ nhớ cache busting, đổi tên tập tin, chạy di chuyển cơ sở dữ liệu và vv.

Với Capistrano nó cũng có thể để triển khai đến nhiều máy cùng một lúc.

2. Các tính năng

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 công việc

Hỗ trợ các infrastructure(cơ sở hạ tầng) Chef-solo

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ôitrường phát triển.

II. Chuẩn bị một project Laravel, install và cấu hình Capistrano

1. Update lại hệ thống

 sudo apt-get update

2. Install Capistrano và config những thông tin cần thiết

Ở đây tôi sử dụng version Laravel 5.2 cho project của mình. Để setup Laravel 5.2 các bạn có thể tham khảo ở link này: https://laravel.com/docs/master/installation.

Trong khuôn khổ bài viết này, tôi tập trung hướng dẫn việc cài đặt và cấu hình Capistrano để có thể deploy code từ git repo về server của mình. Mặc định các bạn đã có source project Laravel 5.2 rồi.

Bây giờ các bạn truy cập vào thư mục projetc của mình

cd path-your-project-root (Đường dẫn đến thư mục project của bạn)

Các bạn chạy lệnh sau để cài Capistrano lên server của mình

sudo gem install capistrano

Sau đó các bạn chạy lệnh

cap install

Các bạn kiểm tra thư mục project của mình sẽ thấy các file và folder như sau.

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

Đây là cấu trúc file và folder của Capistrano. Các bạn cần quan tâm 2 thư mục quan trọng đó là deploylib\capistrano\task

Với file staging.rb trong folder deploy nó tương tự như file production.rb nên tôi sẽ hướng dẫn các bạn làm việc với file staging trước.

File staging.rb

# Don't use `:all`, it's a meta role.

# role :app, %w{[email protected]}, my_property: :my_value
# role :web, %w{[email protected] [email protected]}, other_property: :other_value
# role :db,  %w{[email protected]}

# Configuration
# =============
# You can set any configuration variable like in config/deploy.rb
# These variables are then only loaded and set in this stage.
# For available Capistrano configuration variables see the documentation page.
# http://capistranorb.com/documentation/getting-started/configuration/
# Feel free to add new variables to customise your setup.

# Custom SSH Options
# ==================
# You may pass any option but keep in mind that net/ssh understands a
# limited set of options, consult the Net::SSH documentation.
# http://net-ssh.github.io/net-ssh/classes/Net/SSH.html#method-c-start
#
# Global options
# --------------
#  set :ssh_options, {
#    keys: %w(/home/rlisowski/.ssh/id_rsa),
#    forward_agent: false,
#    auth_methods: %w(password)
#  }
#
# The server-based syntax can be used to override options:
# ------------------------------------
server 'possystem', user: 'pham.ky.khoi', roles: %w{web app db}

Các bạn chỉ cần chú ý dòng này

server 'possystem', user: 'pham.ky.khoi', roles: %w{web app db}

user: Chính là tên login vào server của bạn

Tiếp theo các bạn config file deploy.rb như sau

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

set :application, 'Tên ứng dụng của bạn'
set :repo_url, 'Git repo mà bạn muốn lấy code vể server'

# Default branch is :master
ask :branch, "Branch muốn lấy code về"

# Default deploy_to directory is /var/www/my_app_name
set :deploy_to, 'Thư mục project của bạn'

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

set :use_sudo, true

# set :ssh_options, {
#     keys: %w(~/.ssh/authorized_keys) # Use our local SSH keys
# }

# 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, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')

# Default value for linked_dirs is []
# set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')

# Default value for default_env is {}
# set :default_env, { path: "/opt/ruby/bin:$PATH" }

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

namespace :deploy do

  after :restart, :clear_cache do
    on roles(:web), in: :groups, limit: 3, wait: 10 do
      # Trong đây là nhưng công việc mà bạn muốn thực hiện khi chạy lệnh deploy
    end
  end
end

Khi các bạn chạy lệnh deploy (cap staging deploy). Namespace deploy sẽ được chạy. Lúc đó các bạn hoàn toàn có thể định nghĩa những công việc mà mình muốn chạy như permison folder, migrate database, update composer,... Tất cả các công việc này sẽ được định nghĩa trong task.

Và các task đó sẽ được gọi ở trong namespace deploy.

Tạo task trong Capistrano như thế nào ?

Giả sử, tôi muốn update composer sau khi chạy lệnh deploy. Lúc này trong lib/capistrano/tasks tôi tạo file.

Compser.cap

desc “Running Composer Self-Update”
task :update do
  on roles(:app), in: :sequence, wait: 5 do
    if test “[,-e”,/usr/local/bin/composer”,]”
      execute :composer, “self-update”
    else
      execute :curl,-sS”, “https://getcomposer.org/installer”, “|”, :php
      execute :mv, “composer.phar”,/usr/local/bin/composer”
    end
  end
end

Lúc này các bạn vào file config/deploy.rb và thêm dòng sau vào

namespace :deploy do
   after :updated, “composer:install” # install task
end

Tương tụ, các bạn muốn permison các thư mục hay chạy artisan. Các bạn có thể tạo thêm task mới. Ở đây tôi tạo tasks là Laravel.rb với nội dung như sau:

desc “Setup Laravel folder permissions”
  task :permissions do
    on roles(:app), in: :sequence, wait: 5 do
      within release_path do
        execute :chmod, “u+x artisan”
        execute :chmod,-R 777 app/storage/cache”
        execute :chmod,-R 777 app/storage/logs”
        execute :chmod,-R 777 app/storage/meta”
        execute :chmod,-R 777 app/storage/sessions”
        execute :chmod,-R 777 app/storage/views”
     end
   end
 end

desc “Optimize Laravel Class Loader”
  task :optimize do
    on roles(:app), in: :sequence, wait: 5 do
      within release_path do
        execute :php, “artisan clear-compiled”
        execute :php, “artisan optimize”
    end
 end
end

desc “Run Laravel Artisan migrate task.”
task :migrate do
  on roles(:app), in: :sequence, wait: 5 do
    within release_path do
      execute :php, “artisan migrate”
    end
  end
end

Sau đó các bạn vào file file config/deploy.rb và thêm dòng sau vào

namespace :deploy do
   after :updated, “laravel:permissions”
   after :updated, “laravel:optimize”
   after :updated, “laravel:migrate”
end

Ngoài ra các bạn có thể tạo thêm nhiều tasks mà các bạn muốn như reset apache, reset mysql,...

III. Thực hiện việc deploy

Sau khi các bạn hoàn thành các việc ở trên. Các bạn có thể chạy lệnh sau để thực hiện việc deploy Đối với staging

   cap staging deploy

Ở đây, staging chính là tên file trong folder config/deploy Đối với production

   cap production deploy

Tương tự production cũng vậy.

Kết luận

Ở bài viết này, tôi đã hướng dẫn các bạn cách deploy một project với Capistrano. Nó không giới hạn cho bất kỳ ngôn ngữ nào. Dù project của bạn là PHP hay Ruby.

Trong khuôn khổ bài viết này, tôi chỉ hướng dẫn các tạo một vài tasks đơn giản như trên. Các bạn có thể tự tìm hiểu thêm những tasks khác có thể thêm vào, giúp tiết kiệm được thời gian của mình.

Thanks !