Hôm nay chúng ta sẽ cùng tìm hiểu một công cụ hỗ trợ auto deploy ứng dụng PHP và đặc biệt là với Laravel, đó là Deployer.
1. Cài đặt Deployer
- Để cài đặt Deployer thì cũng khá đơn giản, trên trang chủ Deployer cũng đã hướng dẫn rồi, bạn chỉ cần chạy các câu lệnh sau:
1 2 3 4 | $ curl <span class="token operator">-</span><span class="token constant">LO</span> https<span class="token punctuation">:</span><span class="token comment">//deployer.org/deployer.phar</span> $ mv deployer<span class="token punctuation">.</span>phar <span class="token operator">/</span>usr<span class="token operator">/</span>local<span class="token operator">/</span>bin<span class="token operator">/</span>dep $ chmod <span class="token operator">+</span>x <span class="token operator">/</span>usr<span class="token operator">/</span>local<span class="token operator">/</span>bin<span class="token operator">/</span>dep |
Sau khi cài xong, bạn di chuyển vào thư mục chứa project (ở dưới local) và chạy
1 2 | $ dep init |
thì nó sẽ sinh ra file deploy.php
ở project của bạn
2. Sử dụng Deployer
- Tiếp theo thì chúng ta config với file
deploy.php
1. Configuration
- Để sử dụng biến cấu hình, ta sử dụng hàm
set()
, để lấy nó ra ta sử dụng hàmget()
.
1 2 3 4 5 6 | <span class="token function">set</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'param'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'value'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$param</span> <span class="token operator">=</span> <span class="token function">get</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'param'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
2. Task
- Để định nghĩa các task thực thi, bạn sử dụng hàm
task()
, ngoài ra bạn cũng có thể mô tả cho các task bằng hàmdesc()
, ví dụ:
1 2 3 4 5 | <span class="token function">desc</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'My task'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'my_task'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
- Để thực hiện 1 task:
1 2 | dep my_task |
- Để hiển thị ra các command có sẵn:
1 2 | dep list |
- Bạn cũng có thể gộp nhiều task lại thành 1 task :
1 2 3 4 5 6 7 8 | <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'deploy:prepare'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:update_code'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:vendors'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:symlink'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'cleanup'</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
- Bạn có thể định nghĩa các task có thể chạy trước hoặc sau task khác:
1 2 3 4 5 6 | <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy:done'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">write</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'Deploy done!'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">after</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:done'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
3. Host
- Bạn có thể định nghĩa
host
bằng hàmhost()
, ví dụ:
1 2 3 4 | <span class="token function">host</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'domain.com'</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">></span><span class="token function">stage</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'production'</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">></span><span class="token function">set</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy_path'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'~/app'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Trong đó:
domain.com
: là domain hoặc IP bạn sẽ deploystage
: Tên môi trường bạn sẽ deploy (staging, production) – Bạn để tên gì cũng được miễn sao khi gõ command phải gõ đúng tên stage
4. Flow
- Luồng triển khai chung sẽ như thế này:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'deploy:prepare'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:lock'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:release'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:update_code'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:shared'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:writable'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:vendors'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:clear_paths'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:symlink'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:unlock'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'cleanup'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'success'</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
Trong đó:
deploy:prepare
: Chuẩn bị deploy, kiểm tradeploy_path
tồn tại, nếu không thì tạo nó. Nó cũng kiểm tra tồn tại của các path:relesases
: Trong thư mục này, sẽ lưu trữ các bản releasesshared
: Chia sẻ file trên tất cả các bản releases.dep
: metadata được sử dụng bởiDeployer
deploy:lock
: Khóa deploy để chỉ chạy 1 quá trình deploy đồng thời, kiểm tra sự tồn tại của file.dep/deploy.lock
, nếu quá trình deply bị hủy bởiCtrl + C
thì hãy chạydeploy:unlock
để xóa tệp này đi. Trong trường hợp deploy thất bại, thìdeploy:unlock
sẽ tự động kích hoạtdeploy:release
: Tạo một thư mụcrelease
mới dựa trên cấu hìnhrelease_name
, đồng thời đọc file.dep/releases
để lấy danh sách các bản releases đã tạo trước đó.Ngoài ra, nếu trongdeploy_path
có symlink bản release trước đó, nó sẽ bị xóadeploy:update_code
: pull code từ github vềdeploy:shared
: tạo các tệp và thư mục shared chung cho các file mà chúng ta định nghĩa sẽ share qua các phiên bản. Bạn có thể chỉ định các thư mục và file shared tạishared_dirs
vàshared_files
, quá trình này được chia thành các bước:
+ Copy thư mục từrelease_path
sangshared
nếu không tồn tại.
+ Xóa thư mụcrelease_path
+ symlink thư mục từshared
sangrelease_path
.deploy:writable
: Set quyền ghi cho các file đã được list trongwritable_dirs
.deploy:vendors
: Chạycomposer install
cho ứng dụng.deploy:clear_paths
: Xóa các thư mục được chỉ định trongclear_paths
deploy:symlink
: symlink bản hiện tại sangrelease_path
.cleanup
: Clean các bản release cũsuccess
: In ra thông báo thành công.- Và đây là file cấu hình mình đã config ở file
deploy.php
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | <span class="token php language-php"><span class="token delimiter important"><?php</span> <span class="token keyword">namespace</span> <span class="token package">Deployer</span><span class="token punctuation">;</span> <span class="token keyword">require</span> <span class="token single-quoted-string string">'recipe/laravel.php'</span><span class="token punctuation">;</span> <span class="token comment">// Project name</span> <span class="token function">set</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'application'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy_project'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Project repository</span> <span class="token function">set</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'repository'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'<a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="d1b6b8a591b6b8a5b9a4b3ffb2bebc">[email protected]</a>:name_organizations/name_project.git'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [Optional] Allocate tty for git clone. Default value is false.</span> <span class="token function">set</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'git_tty'</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Default branch</span> <span class="token function">set</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'branch'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'develop'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Shared files/dirs between deploys </span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'shared_files'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'.env'</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'shared_dirs'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'storage'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'bootstrap/cache'</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Writable dirs by web server </span> <span class="token function">add</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'writable_dirs'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'bootstrap/cache'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'storage'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'storage/app'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'storage/app/public'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'storage/framework'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'storage/framework/cache'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'storage/framework/sessions'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'storage/framework/views'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'storage/logs'</span><span class="token punctuation">,</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Hosts</span> <span class="token function">host</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'IP_server_or_domain'</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">></span><span class="token function">user</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy'</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">></span><span class="token function">stage</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'zizou'</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">></span><span class="token function">set</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy_path'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'~/{{application}}'</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">></span><span class="token function">forwardAgent</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Tasks</span> <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'build'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'cd {{release_path}} && build'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'npm:install'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'cd {{release_path}} && npm install'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'npm:run_dev'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'cd {{release_path}} && npm run dev'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'reload:php-fpm'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'sudo /etc/init.d/php7.3-fpm reload'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">task</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span> <span class="token single-quoted-string string">'deploy:info'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:prepare'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:lock'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:release'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:update_code'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:shared'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'npm:install'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'npm:run_dev'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:writable'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:vendors'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'artisan:storage:link'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'artisan:view:clear'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'artisan:cache:clear'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'artisan:config:cache'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:clear_paths'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:symlink'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:unlock'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'cleanup'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'success'</span> <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [Optional] if deploy fails automatically unlock.</span> <span class="token function">after</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy:failed'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'deploy:unlock'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Migrate database before symlink new release.</span> <span class="token function">before</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'deploy:symlink'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'artisan:migrate'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">after</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'cleanup'</span><span class="token punctuation">,</span> <span class="token single-quoted-string string">'reload:php-fpm'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </span> |
Và để chạy thì chúng ta chạy:
1 2 | dep deploy zizou |
^^ hoặc bạn cũng có thể chạy
1 2 | dep deploy zizou <span class="token operator">-</span>vvv |
để xem chi tiết quá trình deploy nó chạy những gì nhé.
Chú ý:
- Để chạy được thằng deploy này thì bạn cần có
ssh key
connect được lên server nhé - Khi chạy lần đầu tiên thì bạn không cho chạy task
migrate
nhé , những lần chạy deploy tiếp theo thì có thể chạy taskmigrate
, và mỗi lần code được merge thì bạn chỉ cần chạy
1 2 | dep deploy |
- Nếu muốn rollback về bản release trước đó thì chỉ cần chạy
1 2 | dep rollback |
- Trên là những gì mình thử với
Deployer
và thành công nhé
Tham khảo