Автоматическое развертывание приложений Laravel с помощью Deployer в Ubuntu 16.04

Laravel – это веб-фреймворк PHP с открытым исходным кодом, который упрощает основные задачи веб-разработки (такие как аутентификация, маршрутизация и кэширование). Deployer – это открытый PHP-инструмент для развертывания со встроенной поддержкой ряда популярных фреймворков, включая Laravel, CodeIgniter, Symfony и Zend Framework.

Deployer автоматизирует развертывание путем клонирования приложения из репозитория Git на сервер и установки зависимостей с помощью Composer. Вам даже не нужно настраивать приложение вручную. Это позволяет тратить больше времени на разработку, а не на загрузку и конфигурацию приложения.

В этом мануале вы научитесь автоматически развертывать приложение Laravel без простоя. Для этого нужно подготовить локальную среду разработки, из которой вы будете развертывать код, а затем настроить производственный сервер (установить Nginx и базу данных MySQL для обслуживания приложения).

Требования

sudo apt-get install php7.0-mbstring php7.0-xml

1: Настройка локальной среды разработки

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

Примечание: Если на локальной машине у вас Windows, используйте эмуляторы оболочки BASH (типа Git bash) для запуска локальных команд.

На локальной машине откройте терминал и загрузите инсталлятор Deployer:

curl -LO https://deployer.org/deployer.phar

Затем запустите короткий PHP-скрипт, чтобы убедиться, что хэш SHA-1 загруженного инсталлятора совпадает с хэшем на странице загрузки Deployer. Ваш хэш будет отличаться:

php -r "if (hash_file('sha1', 'deployer.phar') === '35e8dcd50cf7186502f603676b972065cb68c129') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('deployer.phar'); } echo PHP_EOL;"
Installer verified

Сделайте Deployer глобально доступным. Обратите внимание: если вы используете Windows или macOS на локальном компьютере, вам может понадобиться создать каталог /usr/local/bin/dep перед запуском этой команды:

sudo mv deployer.phar /usr/local/bin/dep

Сделайте его исполняемым:

sudo chmod +x /usr/local/bin/dep

На локальной машине создайте проект Laravel:

composer create-project --prefer-dist laravel/laravel laravel-app "5.5.*"

Локальная среда разработки готова. Теперь можно создать Git-репозиторий для приложения.

2: Подключение удаленного Git-репозитория

Целью Deployer является возможность развернуть код из любого места. Для этого нужно, чтобы пользователи выгружали код в репозиторий в Интернете, из которого Deployer затем копирует его на производственный сервер. Для управления исходным кодом приложения Laravel можно использовать Git, систему управления версиями с открытым исходным кодом. Вы можете подключиться к серверу Git с помощью протокола SSH, и для этого вам необходимо создать SSH-ключи. Это более надежный метод, чем парольная аутентификация, кроме того, вам не придется вводить пароль перед каждым развертыванием.

Выполните следующую команду на локальном компьютере, чтобы сгенерировать SSH-ключи. Флаг -f указывает имя файла ключа (вы можете заменить gitkey своим собственным именем файла). Команда сгенерирует пару ключей SSH (с именем gitkey и gitkey.pub) в папке ~/.ssh/.

ssh-keygen -t rsa -b 4096 -f  ~/.ssh/gitkey

Возможно, на локальном компьютере у вас есть и другие ключи SSH. Чтобы не возникло путаницы, настройте SSH-клиент для использования секретного ключа SSH из новой пары при подключении к серверу Git.

Создайте конфигурационный файл SSH на локальном компьютере:

touch ~/.ssh/config

Откройте файл и добавьте ярлык на сервер Git. Он должен содержать директиву HostName (имя хоста сервера Git) и IdentityFile (путь к файлу только что созданного ключа SSH):

Host mygitserver.com
HostName mygitserver.com
IdentityFile ~/.ssh/gitkey

Сохраните и закройте файл.

Ограничьте к нему доступ:

chmod 600 ~/.ssh/config

Теперь SSH-клиент будет знать, какой секретный ключ использовать для подключения к серверу Git.

Отобразите содержимое файла открытого ключа с помощью следующей команды:

cat ~/.ssh/gitkey.pub

Скопируйте вывод и добавьте открытый ключ на сервер Git.

Если вы используете услугу хостинга Git, ознакомьтесь с ее документацией о том, как добавить ключи SSH в свою учетную запись:

Теперь вы можете подключиться к серверу Git с локальной машины. Проверьте соединение с помощью следующей команды:

ssh -T git@mygitserver.com

Если эта команда приводит к ошибке, убедитесь, что вы правильно добавили SSH-ключи, обратившись к документации хостинга Git, и попробуйте подключиться снова.

Прежде чем загрузить приложение в удаленный репозиторий Git и развернуть его, давайте сначала сконфигурируем производственный сервер.

3: Настройка пользователя Deployer

Deployer использует протокол SSH для безопасного выполнения команд на сервере. По этой причине первое, что нужно для настройки сервера производства – это создание пользователя, которого Deployer может использовать для входа и выполнения команд через SSH.

Войдите на сервер LEMP с помощью пользователя sudo и создайте нового пользователя deployer:

sudo adduser deployer

Laravel требует права на запись в каталогах для хранения кэшированных файлов и загрузки. Поэтому каталоги, созданные пользователем deployer, должны быть доступны для записи веб-серверу Nginx. Добавьте пользователя в группу www-data, чтобы сделать это:

sudo usermod -aG www-data deployer

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

Сделайте это, установив по умолчанию uumask deployer 022:

sudo chfn -o umask=022 deployer

Хранить приложение нужно в каталоге /var/www/html/, поэтому нужно передать права собственности на каталог пользователю deployer и группе www-data.

sudo chown deployer:www-data /var/www/html

Пользователь deployer должен иметь право редактировать файлы и папки в каталоге /var/www/html. Потому все новые файлы и подкаталоги в /var/www/html должны наследовать id группы каталога (www-data). Для этого введите:

sudo chmod g+s /var/www/html

Deployer будет клонировать Git-репозиторий на производственный сервер с помощью SSH, поэтому нужно убедиться, что соединение между вашим сервером LEMP и сервером Git защищено. Здесь можно использовать тот же подход, который вы использовали на локальной машине, и создать ключ SSH для пользователя deployer.

Переключитесь на пользователя deployer на своем сервере:

su - deployer

Затем сгенерируйте пару ключей SSH как пользователь deployer. Теперь можно принять стандартное название файлов ключей SSH.

ssh-keygen -t rsa -b 4096

Отобразите открытый ключ:

cat ~/.ssh/id_rsa.pub

Скопируйте открытый ключ и добавьте его на свой сервер Git, как и ранее.

Ваш локальный компьютер будет связываться с сервером с помощью SSH, поэтому вы должны сгенерировать SSH-ключи для пользователя deployer на локальном компьютере и добавить открытый ключ на сервер.

На локальном компьютере выполните следующую команду. Замените deployerkey своим именем файла ключа:

ssh-keygen -t rsa -b 4096 -f  ~/.ssh/deployerkey

Скопируйте вывод этой команды, в котором будет открытый ключ:

cat ~/.ssh/deployerkey.pub

Теперь перейдите на сервер и запустите эту команду как пользователь deployer:

nano ~/.ssh/authorized_keys

Вставьте открытый ключ в редактор и нажмите Ctrl-X, Y и Enter, чтобы сохранить и выйти.

Ограничьте доступ к файлу

chmod 600 ~/.ssh/authorized_keys

Вернитесь в сессию пользователя sudo:

exit

Теперь ваш сервер может подключиться к серверу Git, и вы можете войти на сервер как deployer с локального компьютера.

Подключитесь с локального компьютера на свой сервер в качестве пользователя deployer, чтобы проверить соединение:

ssh deployer@your_server_ip  -i ~/.ssh/deployerkey

После того как вы войдете в систему как deployer, проверьте соединение между сервером и сервером Git:

ssh -T git@mygitserver.com

Чтобы выйти, введите:

exit

4: Настройка Nginx

Теперь можно настроить веб-сервер, который будет обслуживать приложение. Для этого нужно настроить корневой каталог и структуру каталогов, которые вы будете использовать для хранения файлов Laravel. Настройте Nginx для обслуживания файлов из каталога /var/www/laravel.

Для начала нужно создать конфигурационный файл виртуального хоста (блока server) нового сайта.

Читайте также: Настройка виртуальных хостов Nginx в Ubuntu 16.04

Войдите на сервер как пользователь sudo и создайте новый конфигурационный файл. Не забудьте заменить example.com своим доменным именем:

sudo nano /etc/nginx/sites-available/example.com

В файл поместите блок server:

server {
listen 80;
listen [::]:80;
root /var/www/html/laravel-app/current/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
}

Две директивы listen определяют, какие порты прослушивает веб-сервер, а директива root определяет корневой каталог (document root), в котором будет установлен фреймворк Laravel. current/public в пути к корневому каталогу – это симлинк, который указывает на последний релиз приложения. Директива index позволяет Nginx сначала обслуживать файлы index.php, прежде чем искать их HTML-копии при запросе расположения каталога. Директива server_name должна указывать ваш домен и любые его псевдонимы.

Также нужно изменить способ обработки запросов Nginx. Это делается с помощью директивы try_files. Сначала Nginx должен попытаться выполнить запрос как файл; если он не сможет найти файл с правильным именем, он должен попытаться обслужить index файл по умолчанию для каталога, соответствующего запросу. В противном случае он должен передать запрос в файл index.php в качестве параметра запроса.

server {
listen 80;
listen [::]:80;
root /var/www/html/laravel-app/current/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}

Затем нужно создать блок, который обрабатывает фактическое выполнение файлов PHP. Это применимо к любым файлам, которые заканчиваются на .php. Веб-сервер попробует выполнить сам файл, а затем попытается передать его в качестве параметра в файл index.php.

Директивы fastcgi позволяют Nginx использовать фактический путь приложения (разрешенный после выполнения симлинка) вместо симлинка. Если вы не добавите эти строки в конфигурацию, путь, указанный в симлинке, будет кэширован, и после развертывания будет загружена старая версия вашего приложения. Без этих директив вам придется вручную очищать кэш после каждого развертывания, а из-за этого некоторые запросы не будут обработаны. Кроме того, директива fastcgi_pass гарантирует, что Nginx использует тот же сокет, что и php7-fpm, и что index.php используется как индекс для этих операций.

server {
listen 80;
listen [::]:80;
root /var/www/html/laravel-app/current/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {

include snippets/fastcgi-php.conf;


fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;


fastcgi_param DOCUMENT_ROOT $realpath_root;


fastcgi_pass unix:/run/php/php7.0-fpm.sock;

}

Теперь нужно настроить Nginx для блокировки доступа к скрытым файлам .htaccess. Для этого нужно добавить блок location ~ /\.ht и в пределах этого блока поместить директиву deny all;.

После этого файл будет выглядеть следующим образом:

server {
listen 80;
listen [::]:80;
root /var/www/html/laravel-app/current/public;
index index.php index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}

Сохраните и закройте файл. Затем активируйте новый виртуальный хост, создав симлинк на каталог sites-enabled:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

Проверьте ошибки в конфигурации:

sudo nginx -t

Если команда вернула ошибки, исправьте их и повторите проверку.

Перезапустите Nginx:

sudo systemctl restart nginx

5: Настройка MySQL

После установки MySQL по умолчанию создает пользователя root. Однако у этого пользователя есть неограниченные привилегии, поэтому постоянная работа через этого пользователя root – это риск для безопасности приложения. Лучше создать индивидуального пользователя и БД для приложения.

Войдите в консоль MySQL с правами администратора:

mysql -u root -p

Введите пароль root.

Создайте новую базу данных:

CREATE DATABASE laravel_database DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Затем создайте нового пользователя для базы данных. В этом мануале пользователь называется laravel_user с паролем password (рекомендуем выбрать более надежный пароль).

CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'password';

Передайте этому пользователю права на БД приложения:

GRANT ALL ON laravel_database.* TO 'laravel_user'@'localhost';

Сбросьте привилегии:

FLUSH PRIVILEGES;

Закройте консоль MySQL:

EXIT;

6: Развертывание приложения

Вы уже настроили все инструменты и программы, необходимые для работы Deployer. Все, что осталось сделать перед запуском первого развертывания, — это закончить настройку приложения Laravel и самого Deployer, а также инициализировать и загрузить приложение в удаленный репозиторий Git.

Откройте терминал на локальном компьютере и перейдите в каталог приложения:

cd /path/to/laravel-app

В этом каталоге запустите следующую команду, которая создаст файл deploy.php в папке larvel-app, в нем будут содержаться сведения о конфигурации и задачи для развертывания:

dep init -t Laravel

Затем откройте файл deploy.php в текстовом редакторе. В третьей строке указан скрипт PHP, который содержит необходимые задачи и конфигурации для развертывания приложения Laravel:

<?php
namespace Deployer;
require 'recipe/laravel.php';
. . .

Эти поля вы должны отредактировать согласно вашей конфигурации:

  • В разделе // Project Name укажите имя вашего проекта Laravel.
  • В // Project Repository добавьте ссылку на репозиторий Git.
  • В разделе // Hosts  добавьте IP-адрес или доменное имя вашего сервера в директиву host(), а в директиве user() укажите имя пользователя Deployer (здесь это deployer). Также нужно добавить ключ SSH, созданный в разделе 3, в директиву identFile(), и путь к каталогу, в котором находится приложение.

После редактирования файл выглядит так:

...
// Project name
set('application', 'laravel-app');
// Project repository
set('repository', 'git@mygitserver.com:username/repository.git');
. . .
// Hosts
host('your_server_ip')
->user('deployer')
->identityFile('~/.ssh/deployerkey')
->set('deploy_path', '/var/www/html/laravel-app');

Затем закомментируйте последнюю строку файла (before(‘deploy:symlink’, ‘artisan:migrate’);.). Эта строка позволяет Deployer автоматически запускать миграцию базы данных; закомментировав ее, вы отключите эту функцию. Если вы не сделаете этого, развертывание завершится неудачно, так как этой строке нужны соответствующие учетные данные на сервере, а их можно добавить только с помощью файла, который будет создан во время первого развертывания.

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

Прежде чем развернуть проект, нужно сначала загрузить его в репозиторий Git.

На локальной машине откройте каталог приложения:

cd /path/to/laravel-app

Выполните следующую команду в каталоге laravel-app, чтобы инициализировать репозиторий Git в папке проекта:

git init

Добавьте в него все файлы проекта.

git add .

Зафиксируйте изменения с помощью коммита:

git commit -m 'Initial commit for first deployment.'

Добавьте сервер Git в локальный репозиторий с помощью следующей команды. Обязательно укажите свой URL-адрес удаленного репозитория.

git remote add origin git@mygitserver.com:username/repository.git

Загрузите изменения в удаленный репозиторий Git.

git push origin master

Запустите первое развертывание с помощью dep:

dep deploy

Если развертывание прошло успешно, вы увидите такой вывод и сообщение «Successfully deployed!»:

✈︎ Deploying master on your_server_ip
✔ Executing task deploy:prepare
✔ Executing task deploy:lock
✔ Executing task deploy:release
➤ Executing task deploy:update_code
✔ Ok
✔ Executing task deploy:shared
✔ Executing task deploy:vendors
✔ Executing task deploy:writable
✔ Executing task artisan:storage:link
✔ Executing task artisan:view:clear
✔ Executing task artisan:cache:clear
✔ Executing task artisan:config:cache
✔ Executing task artisan:optimize
✔ Executing task deploy:symlink
✔ Executing task deploy:unlock
✔ Executing task cleanup
Successfully deployed!

На сервере внутри каталога /var/www/html/laravel-app будет создана следующая структура:

├── .dep
├── current -> releases/1
├── releases
│   └── 1
└── shared
├── .env
└── storage

Проверьте это, выполнив следующую команду на своем сервере:

ls /var/www/html/laravel-app
current  .dep  releases  shared

Вот что содержит каждый из этих файлов и каталогов:

  • Каталог releases содержит версии развертывания приложения Laravel.
  • current – симлинк на последнюю версию.
  • Каталог .dep содержит специальные метаданные для Deployer.
  • Каталог shared содержит конфигурационный файл .env и каталог storage, который будет привязан симлинком к каждой версии.

Однако приложение пока не работает, поскольку файл .env пуст. Этот файл используется для хранения важных конфигураций, таких как ключ приложения (это случайная строка, используемая для шифрования). Если этот ключ не установлен, ваши пользовательские сессии и другие данные не будут шифроваться. Приложение имеет файл .env на локальном компьютере, но файл .gitignore от Laravel исключает его из репозитория Git, поскольку хранение конфиденциальных данных (например, паролей) в репозитории Git не рекомендуется. Файл .env также содержит параметры подключения к базе данных, поэтому мы отключили миграцию базы данных для первого развертывания.

Настройте приложение на своем сервере.

Войдите как deployer:

ssh deployer@your_server_ip  -i ~/.ssh/deployerkey

На сервере запустите следующую команду, скопируйте и вставьте ваш файл .env в редактор.

nano /var/www/html/laravel-app/shared/.env

Прежде чем сохранить его, вы должны внести некоторые изменения. В APP_ENV укажите production, в APP_DEBUG false, в APP_LOG_LEVEL – error. Также не забудьте указать базу данных, пользователя БД и пароль. Кроме того, нужно заменить example.com своим доменом.

APP_NAME=Laravel
APP_ENV=production
APP_KEY=base64:cA1hATAgR4BjdHJqI8aOj8jEjaaOM8gMNHXIP8d5IQg=
APP_DEBUG=false
APP_LOG_LEVEL=error
APP_URL=http://example.com
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_database
DB_USERNAME=laravel_user
DB_PASSWORD=password
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

Сохраните и закройте файл.

Раскомментируйте последнюю строку файла deploy.php на локальной машине:

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

Важно! Это включит автоматическую миграцию базы данных при каждом развертывании. Благодаря этому не нужно переносить базы данных вручную, но не забудьте создать резервную копию БД перед развертыванием.

Чтобы убедиться, что конфигурация работает, разверните приложение еще раз. Выполните следующую команду на локальном компьютере:

dep deploy

Теперь ваше приложение будет работать правильно. Если вы посетите доменное имя своего сервера в браузере, вы увидите целевую страницу Laravel.

Перед развертыванием вам не нужно редактировать файл .env на своем сервере. Остальные развертывания не так сложны, как первое, и выполняются всего несколькими командами.

7: Запуск развертывания

В этом разделе рассмотрим процесс базового развертывания.

Измените что-нибудь в приложении перед повторным развертыванием. Например, вы можете добавить новый маршрут в файл routes/web.php:

<?php
. . .
Route::get('/', function () {
return view('welcome');
});
Route::get('/greeting', function(){
return 'Welcome!';
});

Отправьте коммит этих изменений:

git commit -am 'Your commit message.'

Загрузите изменения в репозиторий Git:

git push origin master

Разверните приложение:

dep deploy

Вы успешно развернули приложение на сервере.

Заключение

Больше информации о Deployer можно найти в документации проекта.

Tags: , , , , ,