Долгое время я деплоил вручную: ssh на сервер, git pull, composer install, artisan migrate. Работало, но было скучно и подвержено ошибкам. Потом я потратил вечер на настройку GitHub Actions, и теперь всё деплоится в одну кнопку (ну, точнее, в один push).
Зачем это нужно
На каждый push в main у меня теперь запускается pipeline, который собирает зависимости, проверяет качество кода (базовые линтеры), логится на VPS по SSH, делает git pull, запускает миграции и перезагружает php-fpm. Занимает минут 5-7, зато можно спокойно пить кофе и не беспокоиться, что забыл запустить миграции.
Как я это сделал
Для VPS нужны два ключа: deploy key (для доступа к репозиторию) и SSH ключ (для доступа на сервер). Deploy key добавляется в GitHub как read-only, SSH ключ хранится в secrets GitHub Actions.
name: Deploy to VPS
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: |
cd /var/www/pswrk
git pull origin main
composer install --no-dev
php artisan migrate --force
php artisan cache:clear
systemctl reload php8.3-fpm
Это базовый вариант. Потом я добавил проверку статуса деплоя, откат если что-то пошло не так, и нотификацию в Telegram (да, через бота).
# Telegram нотификация (дополнительный шаг в workflow)
curl -X POST https://api.telegram.org/bot$BOT_TOKEN/sendMessage \
-d chat_id=$CHAT_ID \
-d text="Deployment completed: $COMMIT_MESSAGE"
Что я узнал
SSH keys — это важно. Не пытайтесь использовать один ключ везде. Создавайте отдельные ключи для разных сервисов. Deploy key для GitHub — отдельный, VPS SSH — отдельный.
Secrets нужны. Никогда не коммитьте SSH ключи или пароли. GitHub Secrets хранит их в шифрованном виде и подставляет в переменные окружения.
Бот-нотификация — must have. Я добавил уведомления в Telegram о каждом деплое. Если что-то пошло не так, узнаю моментально.
Миграции с --force обязательны. В боевой среде Laravel по умолчанию не запускает миграции автоматически. Нужен флаг --force.
Если до сих пор деплоите вручную — потратьте вечер на настройку GitHub Actions. Оно того стоит.