Deployer – Các bước setup deployment cho project PHP

Deployer là gì!?

Nói nôm na cho dễ hiểu, deployer là công cụ giúp chúng ta deploy application lên cloud và được viết bằng PHP, hỗ trợ cho rất nhiều framework phổ biến như Laravel.

Tại sao nên sử dụng Deployer?

  1. Để ứng dụng của chúng ta chạy được trên server mới toanh, chắc chắn sẽ cần phải cài đặt và setup đủ các thứ như mySQL, PHP, SSL,… rất cực. Deployer sẽ thực hiện nhưng việc phức tạp đó cho mình, việc chúng ta cần làm là viết 1 file config, và click chuột.
  2. Nếu không có Deployer, mỗi lần chúng ta deploy application phải thực hiện các bước cơ bản như thông báo với khách hàng trang web sẽ tạm dừng để update mới, hay bật chế độ bảo trì,… nhiều thứ và chăc chắn sẽ có downtime. Nhưng với Deployer, chúng ta không cần phải lo vấn đề downtime nữa, trang web vẫn sẽ hoạt động bình thường cho đến khi deploy hoàng tất, application sẽ tự động update phiên bản mới nhất.
  3. Deployer phù hợp với hầu hết các framework và ứng dụng.

Setup Deployer với Laravel như thế nào?

Từ khúc này trở đi tôi sẽ giới thiệu cách setup Deployer với Laravel application nha. Các PHP framework khác cũng tương tự như vậy.

Cài đặt Deployer:

composer require deployer/deployer --dev

Bây giờ chúng ta sẽ sử dụng được lệnh dep, các bạn cứ nghĩ rằng lệnh dep cũng giống như câu php artisan nhưng mà dùng để chạy các câu lệnh deploy.

Tiếp theo ta cần 1 file config tên deploy.php, có nhiều cách để tạo file này, sau đây tôi sẽ giời thiệu các bạn 2 cách:

  • Chúng ta chạy câu lệnh sau đây, Deployer sẽ tự động tạo cho mình 1 file deploy config. Sau khi enter, nó sẽ hỏi chúng ta vài câu hỏi, việc mình làm là trả lời thôi, còn lại Deployer sẽ tự động làm hết:
dep init
  • Hoặc sử dụng cách đơn giả hơn là copy file deploy.php mà tôi đã viết sẵn các thứ, bỏ vào thư mục root của project, và xong:
<?php
namespace Deployer;

require 'recipe/laravel.php';

// Project name
set('application', 'Example');

// Project repository
set('repository', 'tungnt92@github.com:/EXAMPLE/example-project.git');

// [Optional] Allocate tty for git clone. Default value is false.
set('git_tty', false);

// Windows needs to disable ssh multiplexing
set('ssh_multiplexing', false);  #(if Windows  uncomment this)

// remove default time out
// for those who have huge repo or crappy connection
set('default_timeout', null);

// Shared files/dirs between deploys
add('shared_files', []);
set('shared_dirs', [
    'storage'
]);

// Writable dirs by web server
add('writable_dirs', [
    'storage'
]);
set('allow_anonymous_stats', false);

// Hosts
foreach (glob('deploy/config/*.php') as $file) {
    require_once $file;
}

// Tasks
foreach (glob('deploy/tasks/*.php') as $file) {
    require_once $file;
}

// [Optional] if deploy fails automatically unlock.
after('deploy:failed', 'deploy:unlock');

// Migrate database before symlink new release.
before('deploy:symlink', 'artisan:migrate');

// Clear Apache cache after finish deployment
after('deploy:symlink', 'clear_apache_cache');

Ở đây các bạn cần lưu ý những chỗ sau:

  • Chỗ Repository, chỗ này nó kiêu mình hãy nhập git URL của project vào đi, Deployer dùng để clone project của chúng ta vào server.
  • Host, các bạn sẽ thấy chỗ này tôi viết vòng loop này kia, mục đích là tôi để tất cả config liên quan đến server ở chỗ khác, trong trường hợp này là deploy/config/, mục đích là nhìn cho nó gọn và đẹp.
    Các bạn có thể làm giống tôi, hoặc replace chỗ đó thành đoạn code như sau cũng được:
...

host('xx.xx.xx.xx')
    ->stage('develop')
    ->user('bitnami')
    ->forwardAgent(true)
    ->identityFile('docs/aws/server-key-dev.pem')
    ->set('branch', 'develop')
    ->set('deploy_path', '/home/bitnami/htdocs/project');

...
  • Tiếp theo các bạn để ý chỗ Task, ở đoạn này tôi dành để khai báo những task cần thiết trên server, tất cả các dòng code thuộc về những task này tôi để trong thư mục deploy/tasks/. Những task mà tôi cần chạy như set_apache_owner, clear_apache_cache… tùy nhu cầu của các bạn nhé. Lưu ý là tôi chỉ mới khai báo thôi nhé, chưa chạy!!!
<?php

namespace Deployer;

desc('Set apache user as owner deploy folder');
task('permission:set_apache_owner', function () {
    $deploy_path = get('deploy_path');
    $deploy_user = get('deploy_user');
    $command = "sudo chown -R {$deploy_user}:daemon {$deploy_path}";

    run($command);
});
<?php

namespace Deployer;

desc('Clear apache cache, link new release to current');
task('clear_apache_cache', function () {
    run('sudo php /home/bitnami/htdocs/mypage/cachetool.phar opcache:reset --fcgi=/opt/bitnami/php/var/run/www.sock');
});
  • Tiếp theo là task clear_apache_cache, khi các bạn deploy source mới lâu lâu sẽ có trường hợp như: “Sao code mình mới deploy lên tức thì sao vào web nó lại là code cũ!? Chưa chịu update code mới! Sao kỳ quá vậy,…”.Khi gặp trường hợp này tôi đề nghị các bạn nên check lại cache ở server hoặc nếu các bạn xài Cloudfront thì check cache ở đó. Trong trường hợp này tôi chủ động clear cache của Apache.
    Các bạn đọc bài sau để biết thêm chi tiết về cacheTool mà tôi xử dụng ở đây nhé: https://deployer.org/docs/7.x/contrib/cachetool
  • Tiếp theo các bạn khai báo những thông tin còn lại như SSH key, deploy path,…

Thực hiện deploy:

Bước này coi như các bạn đã 99% hoàn thành và có thể deploy application của mình lên server rồi, các câu lệnh thường dùng để deploy với cú pháp như sau:

php vendor/bin/dep deploy [stage]

Lưu ý chỗ stage các bạn thay thế alias của server tương ứng vào nhé:

php vendor/bin/dep production 

Happy hacking 🙂