Развертывание Laravel 8 с нулевым временем простоя (3 часть)

Доброго времени суток!

В данном эпизоде, мы с вами переходим к самому интересному, а именно, пакетунепрерывного развертывания — Deployer.

Это «утилита», которая позволяет разворачивать приложения, созданные на разных фреймворках и CMS (Laravel, WordPress и другие), а также создавать свои «рецепты» деплоя.

Итак, у нас локально есть проект на Laravel, для которого нужно установить следующую зависимость:

composer require deployer/deployer --dev

Проверить работу и получить весь список команд, можно:

php vendor/bin/dep

Теперь нам необходимо инициализировать наш файл конфигурации развертывания.

php vendor/bin/dep init

Вам будут заданы вопросы, на которые я бы посоветовал ответить следующим образом:

  • Формат — YAML
  • Шаблон проекта — Laravel
  • Дважды жмем ENTER, на вопросах о гит репозитории проекта. Если у Вас был инициализирован GIT для проекта — эти поля заполнятся автоматически. В противном случае, необходимо будет указать эти данные.
  • Псевдоним сервера — production

Теперь, в корне нашего проекта, должен быть появится файл deploy.yaml, который выглядит таким образом:

import: 
  - recipe/laravel.php

config:
  application: 'testmysite.pro'
  repository: '[email protected]:den4ela/testmysite.pro.git'

hosts:
  prod:
    deploy_path: '~/{{application}}'

tasks:
  build:
    script:
      - 'cd {{release_path}} && npm run build'

after:
  deploy:failed: deploy:unlock

Я не буду сейчас описывать, что означает каждый параметр этого файла. Ниже, я предоставляю свой финальный файл deploy.yaml. После, обсудим все детальнее.

import:
    - recipe/laravel.php
    - contrib/php-fpm.php
    - contrib/npm.php

config:
  application: 'testmysite.pro'
  repository: '[email protected]:den4ela/testmysite.pro.git'
  remote_user: root
  deploy_path: '/var/www/testmysite.pro'
  php_fpm_version: '8.0'

hosts:
  production_1:
      hostname: '92.53.69.30'

tasks:
  robots:
    script:
      - cd {{deploy_path}}/current/public
      - rm -f robots.txt
      - ln -s {{deploy_path}}/shared/robots.txt robots.txt

  deploy:
    - 'deploy:prepare'
    - 'deploy:vendors'
    - 'artisan:storage:link'
    - 'artisan:view:cache'
    - 'artisan:config:cache'
    - 'artisan:route:cache'
    - 'artisan:down'
    - 'artisan:route:cache'
    - 'artisan:view:cache'
    - 'artisan:config:cache'
    - 'artisan:migrate'
#     - 'artisan:db:seed'
    - 'artisan:up'
#     - 'npm:install'
#     - 'npm:run:prod'
    - 'deploy:publish'
    - 'php-fpm:reload'
    - 'robots'

after:
  deploy:failed: deploy:unlock

Описание разделов

Секция «import»

Данная секция позволяет импортировать дополнительные файлы конфигурации в наш основной файл. Она принимает массив файлов для импорта и объединяет их с нашими конфигурациями. Порядок имеет значение, поскольку в случае конфликтов последняя конфигурация имеет приоритет над предыдущими.

В Deployer такой файл называется «рецептом».

Рецепт может быть написан как YAML, так и на PHP. Все зависит от сложности задачи.

По умолчанию, у нас импортирован рецепт recipe/laravel.php. Но я также добавил скрипты для работы с PHP-FPM и NPM.

import:
    - recipe/laravel.php
    - contrib/php-fpm.php
    - contrib/npm.php

Секция «config»

Данная секция позволяет хранить данные в формате ключ-значение, для использования внутри сценария развертывания.

Для получения значения, необходимо просто обернуть ключ в двойные фигурные скобки.

config:
  first_name: 'Denis'
  hello_message: 'Hello! My name is {{first_name}}.'

Как видите, все просто. По умолчанию, данная секция содержит ключи application и repository. Это очень важный момент, так как эти ключи необходимы для работы скрипта, так как они используются для клонирования проекта из GIT репозитория.

Далее, я добавил следующие ключи, где указал имя пользователя нашего сервера (root), путь к папке где необходимо будет развернуть среду нашего проекта (deployer автоматически создаст папку current) и версию PHP-FPM.

  remote_user: root
  deploy_path: '/var/www/testmysite.pro'
  php_fpm_version: '8.0'

Секция «hosts»

В качестве демонстрации я использую пользователя root на сервере, что крайне не рекомендую делать у себя на продакшн серверах и в теории, у меня будет одинаковый пользователь на всех серверах и путь к проекту, что позволяет мне задать единый путь и пользователя в секции «config», а в данной секции, просто перечислить мои сервера

hosts:
  production_1:
      hostname: '92.53.69.30'
  production_2:
      hostname: '92.53.69.31'
  production_3:
      hostname: '92.53.69.32'

Итого, данный инструмент способен разворачивать приложение сразу на нескольких серверах!

Если у Вас сервера отличаются друг от друга пользователем или путем к проекту, следует указывать следующим образом, удалив соответствующие значения из секции «config»:

production_1:
    remote_user: root
    hostname: '92.53.69.30'
    deploy_path: '/var/www/testmysite.pro'

Секция «tasks»

Это самая важная секция. Все процессы, вызываются именно отсюда. Как я говорил ранее, мы могли создать формат файла .php и тогда бы, можно было построить процесс иным образом:

<?php

namespace Deployer;

task('nginx:restart', function () {
  run('service nginx restart');
});

Для демонстрации работы и простоты написания, я использую язык YAML, вместо PHP.

У меня есть задача «robots», которая создает ссылку на файл robots.txt. Так как приложение может работать на зеркале, то в этом файле я прописываю запрет на индексацию поисковыми роботами, а на продакшн, соответственно, нормальные настройки. Это опциональная задача и вы ее можете удалить.

tasks:
  robots:
    script:
      - cd {{deploy_path}}/current/public
      - rm -f robots.txt
      - ln -s {{deploy_path}}/shared/robots.txt robots.txt

В задаче «deploy» описываются стандартные действия, в конце, есть 2 команды, первая из которых перезапускает PHP-FPM, а вторая, как вы догадались, запускает задачу «robots».

deploy:
#...
    - 'php-fpm:reload'
    - 'robots'

Секция «after»

Как вы могли догадаться, эта секция выполняется по завершению предыдущих задач. По умолчанию в данной секции есть задача, которая говорит — «если что то пошло не так deploy:failed — сними блокировку с этого хоста».

after:
  deploy:failed: deploy:unlock

По умолчанию Deployer добавляет блокировку к каждому хосту во время развертывания и снимает ее в самом конце. Это гарантирует, что если два человека попытаются выполнить развертывание одновременно — то только один из вас добьется успешного развертывания.


Также есть секция «before», но об этом вы можете прочитать в документации Deployer. Не хочу перегружать Вас лишней информацией, которая не относится к данному уроку.

Давайте пройдемся по основным консольным командам.

php vendor/bin/dep

  • list — список всех доступных задач
  • init — инициализация вашего файла deployer .php/.yaml
  • <task> — запустить определенную задачу (robots или deploy)
  • ssh — создаст ssh тунель с указанным сервером
  • logs — отобразит список событий

Обратите внимание, что вы можете указать хост в конце большинства этих команд, например, мы хотим создать ssh тунель с сервером «production_1»:

php vendor/bin/dep ssh production_1

Вывод

Сегодня мы с вами настроили инструмент Deployer, но до сих пор не запустили его, это мы сделаем в следующем эпизоде.

Я безумно рад, что Вы дочитали до этого момента и если у Вас все получилось — большие молодцы.

Я с Вами не прощаюсь, увидимся в следующем уроке 😉.