Zero Downtime Deployment với Laravel Envoy
Thời kỳ "kéo thả FTP" đã qua. Ngay cả "git pull" trên server cũng rủi ro (nếu composer install fail giữa chừng thì sao? Trang web của bạn sẽ bị hỏng).
Zero Downtime Deployment có nghĩa là người dùng không bao giờ thấy trang lỗi trong quá trình cập nhật. Chúng ta đạt được điều này bằng cách clone code vào thư mục MỚI, thiết lập nó, và sau đó đổi symlink.
Laravel Envoy là công cụ để chạy các tác vụ SSH trên server remote sử dụng cú pháp Blade.
Cài Đặt
composer global require laravel/envoy
File Envoy.blade.php
Tạo file này trong thư mục gốc của project.
@servers(['web' => 'user@192.168.1.1'])
@setup
$repository = 'git@github.com:user/repo.git';
$releases_dir = '/var/www/my-app/releases';
$app_dir = '/var/www/my-app';
$release = date('YmdHis');
$new_release_dir = $releases_dir .'/'. $release;
@endsetup
@story('deploy')
clone_repository
run_composer
update_symlinks
@endstory
@task('clone_repository')
echo 'Cloning repository'
[ -d {{ $releases_dir }} ] || mkdir {{ $releases_dir }}
git clone --depth 1 {{ $repository }} {{ $new_release_dir }}
@endtask
@task('run_composer')
echo "Starting deployment ({{ $release }})"
cd {{ $new_release_dir }}
composer install --prefer-dist --no-scripts -q -o
@endtask
@task('update_symlinks')
echo "Linking storage directory"
rm -rf {{ $new_release_dir }}/storage
ln -nfs {{ $app_dir }}/storage {{ $new_release_dir }}/storage
echo 'Linking .env file'
ln -nfs {{ $app_dir }}/.env {{ $new_release_dir }}/.env
echo 'Switching current symlink (Atomic Switch)'
ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current
@endtask
Cách Chạy
envoy run deploy
Tại Sao Điều Này An Toàn
Bước quan trọng là ln -nfs {{ $new_release_dir }} {{ $app_dir }}/current.
Cập nhật symlink là atomic trong Linux. Nó xảy ra ngay lập tức.
Các request trước khi đổi sẽ đến thư mục cũ. Các request sau khi đổi sẽ đến thư mục mới. Không có file bị hỏng ở giữa.
Nếu composer install fail, script dừng lại, và symlink không bao giờ được đổi. Trang web của bạn vẫn online.