Deployer — зручний і гнучкий деплой додатків

Безперечно, тема, думаю, багатьма заїжджена до дірок — все-таки, деплой треба робити для кожного проекту — але я все ж підніму її і розповім про один чудовому інструменті, про який, з якоїсь дивної причини, досі нічого не написали на Хабре, та й взагалі в російськомовному сегменті як-то про нього мало що написано. Виправимо це непорозуміння.
Deployer гарний у багатьох відношеннях. Код скрипта для деплоя виходить коротким. Написаний на старому доброму Пыхчанском, запакований у самоисполняемый бінарники — тобто, ставити окремо якісь інші інструменти на сервер вам не доведеться. Чому б і не заюзать його в своїх проектах?
Написав утиліту якийсь Антон Медведєв, у нього до речі досить приємний блог є. Спасибі тобі, Антон :)
Перший комміт був зроблений аж у 2013-му році, і досі інструмент потихеньку розвивається. У нього також є приємний сайт, на якому можна знайти про нього всю документацію.
Що особисто мені подобається найбільше з того, що дає даний інструмент — це можливість швидко відкотитися на минулий "робочий" реліз, якщо новий реліз виявився невдалим. Також досить зручно те, що якщо при спробі "викотити" новий реліз щось піде не так (міграції не застосувались, фронтенд файли не скомпилировались, тести не прогнались..) — то ваше поточне працююче додаток це ніяк не торкнеться — воно буде працювати як ні в чому не бувало. Справа в тому, що Deployer не змінить посилання у директорії, що позначає поточний активний реліз, до того моменту, поки ваш новий "реліз" не буде повністю встановлений і готовий до роботи.
Єдине, чого Deployer не вирішує — це можливі проблеми із застосуванням міграцій до вашої бази даних. Але це взагалі тема складна, не знаю, чи існують взагалі елегантні рішення в даному випадку. Якщо існує — буду радий дізнатися, яке.
Структура папок релізів
Весь проект поділяється на три папки:
current
,
releases
та
shared
. Загалом, це досить поширений вид для подібних інструментів, і він дійсно зручний. Скажімо, в одному з моїх проектів на Laravel ця структура виглядає ось так:

current
— посилання на папку останнього успішно зібраного релізу, тобто поточний додаток.
releases
— всі релізи, які були зібрані. За замовчуванням зберігається тільки останні три релізу, і це значення можна легко поміняти.
shared
— папка, в якій знаходяться всі "загальні" файли, які відносяться до всіх релізах одночасно і не повинні створюватися кожен раз заново. Приміром — файл
.env
, завантажені користувачами файли, і так далі.
Приклад скрипта деплоя Laravel програми
Я люблю особисто зайти на свій сервер, запустити скрипт деплоя і спостерігати за процесом його роботи. Просто, мені так набагато спокійніше жити, так як я завжди можу зробити якісь термінові заходи, якщо при деплое щось піде не так. А так, як я знаю, люди зазвичай запускають подібний скрипт зі своєї локальної машини, яка підключається по SSH до сервера і виробляє деплой. Якщо це треба зробити відразу на декількох машинах — то такий підхід, звичайно, буде зручніше. До речі, Deployer дозволяє виконувати деплой відразу на декількох машинах у тому числі.
Звісно, перед тим як отримати можливість виконати цей скрипт, вам необхідно спочатку встановити Deployer на свою систему.
В одному з моїх проектів на Laravel 5 скрипт деплоя
deploy.php
виглядає наступним чином:
<?php

// Підключимо основні рецепти з Deployer'а
require 'recipe/common.php';
require 'recipe/laravel.php';

// Вкажемо основні параметри деплоя
localServer('local', 'localhost')
->user('{ваш користувач}')
->env('deploy_path', '/path/to/project/dir')
->stage('local')
;

set('repository', '{ваш-git-репозиторій.git}');
env('branch', '{гілка-для-релізів}');

env('git_cache', true);

// Загальні папки для вашого проекту, які будуть прозоро доступні всім релізам
// Вони не будуть створюватися заново при новому релізі, замість них будуть створені
// посилання на їх однойменні папки в папці shared
set('shared_dirs', [
'storage/app',
'storage/framework/cache',
'storage/framework/sessions',
'storage/framework/views',
'storage/logs',
'public/uploads',
'node_modules',
]);

// Загальні файли. Принцип такий же, як з папками
// У випадку з Laravel нам необхідно зробити "загальним" лише один
// файл - .env
set('shared_files', ['.env']);

// Папки, в які програма повинна мати можливість
// писати дані. У нашому випадку - це три директорії
set('writable_dirs', ['storage', 'vendor', 'public/uploads' ]);

set('http_user', '{ваш користувач}');
set('composer_command', '/usr/local/bin/composer'); // Шлях до розташування Composer'а

// Завдання для деплоя. Встановити NPM компоненти
task('deploy:install-npm', function() {
run('cd {{release_path}} && npm i');
});

// Ще одне завдання: зібрати всі фронтенд файли, в моєму випадку
// це робиться через Grunt.js
task('deploy:compile-assets', function() {
run('cd {{release_path}} && grunt deploy-production');
});

// Виконати міграції
task('deploy:migrations', function() {
run('cd {{release_path}} && php artisan migrate --force');
});

// Створити кеш для правил роутінга
task('deploy:create-route-cache', function() {
run('cd {{release_path}} && php artisan route:cache');
});

// Створити кеш файлів конфігурацій
task('deploy:create-config-cache', function() {
run('cd {{release_path}} && php artisan config:cache');
});

// Очистити всі закешовані дані
task('deploy:clean-cached-data', function() {
run('cd {{release_path}} && rm bootstrap/cache/*');
});

// Перезапустити PHP після успішного деплоя
task('reload:php-fpm', function() {
run('sudo /usr/sbin/service php7.0-fpm restart');
});

task('deploy', [
'deploy:prepare',
'deploy:release',
'deploy:update_code', // Скачати останній код з гитхаба
'deploy:shared', // Створити посилання на загальні дані
'deploy:vendors', // Оновити компоненти композера
'deploy:clean-cached-data', // Очистити всі закешовані дані
'deploy:create-route-cache', // Створити кеш для правил роутінга
'deploy:create-config-cache', // Створити кеш файлів конфігурацій
'deploy:install-npm', // Оновити компоненти NPM
'deploy:compile-assets', // Скомпілювати фронтенд файли
'deploy:migrations', // Застосувати міграції
'deploy:symlink', // створити посилання поточного релізу на цей
'cleanup',
])->desc('Deploy your project');

after('deploy', 'success');
after('deploy', 'reload:php-fpm');
after('rollback', 'reload:php-fpm');

Також у мене є пара маленьких файлів, що розташовані поряд з вищевказаним файлом:
start-deploy.sh
та
rollback-deploy.sh
. Для того щоб швидко запустити деплой або, відповідно, відкотити його.
Файл
start-deploy.sh
:
dep deploy local

Файл
rollback-deploy.sh
:
dep rollback local

Отже, щоб запустити процес деплоя, нам залишається набрати лише одну команду в Bash'е:
./start-deploy.sh

Таким чином, як ми бачимо, ввівши всього одну команду, ми змусимо сервер виконати всі необхідні кроки для розгортання нашого проекту. І тільки якщо все пройшло добре, папка
current
змінить посилання на новий реліз і перезавантажить PHP після всього цього.
У загальному-те, це все, що я хотів розповісти і показати. Сподіваюся, це буде комусь корисним. Ну і звичайно цікаво буде дізнатися думку інших людей про те, як вони займаються деплоем своїх додатків.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.