Разбираем правильный пайплайн: атомарный деплой, откат за 10 секунд, нет простоя.
1️⃣ Устанавливаем Deployer
composer require deployer/deployer --dev
Генерируем базовый конфиг:
./vendor/bin/dep init
Выбираем тип проекта (Laravel, Symfony, Common). Получаем deploy.php в корне.
2️⃣ Конфигурируем хосты и пути
// deploy.php
import('recipe/laravel.php');
host('production')
->setHostname('your-server.com')
->setRemoteUser('deploy')
->setDeployPath('/var/www/app')
->setSshMultiplexing(true);
set('shared_files', ['.env']);
set('shared_dirs', ['storage', 'bootstrap/cache']);
set('writable_dirs', ['storage', 'bootstrap/cache']);
set('keep_releases', 5);
keep_releases: 5 — держим 5 последних релизов на сервере. Откат мгновенный.3️⃣ Понимаем структуру директорий
Deployer создаёт на сервере:
/var/www/app/
├── current -> releases/20250311120000/ # symlink
├── releases/
│ ├── 20250311120000/
│ └── 20250310090000/
└── shared/
├── .env
└── storage/
current — это симлинк. Переключение релиза = атомарная замена симлинка. Nginx видит новый код без перезапуска.
4️⃣ Добавляем кастомные задачи
task('artisan:migrate', function () {
run('cd {{release_path}} && php artisan migrate --force');
});
task('opcache:reset', function () {
run('kill -USR2 $(cat /var/run/php-fpm.pid)');
});
// порядок выполнения
after('deploy:symlink', 'opcache:reset');
before('deploy:symlink', 'artisan:migrate');Миграции — до переключения симлинка. OPcache сброс — после. Последовательность важна.
5️⃣ GitHub Actions пайплайн
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
- name: Install dependencies
run: composer install --no-dev --optimize-autoloader
- name: Deploy
run: ./vendor/bin/dep deploy production -vvv
env:
SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
Секрет DEPLOY_SSH_KEY — приватный ключ деплой-юзера без sudo, только для деплоя.
6️⃣ Настраиваем деплой-юзера на сервере
useradd -m -s /bin/bash deploy
mkdir -p /home/deploy/.ssh
# вставляем публичный ключ
echo "ssh-ed25519 AAAA..." >> /home/deploy/.ssh/authorized_keys
chmod 700 /home/deploy/.ssh && chmod 600 /home/deploy/.ssh/authorized_keys
# права на директорию приложения
chown -R deploy:www-data /var/www/app
chmod -R 775 /var/www/app
PHP-FPM должен работать от www-data. Deployer деплоит от deploy. Группа общая.
7️⃣ Откат при провале
// автоматический откат если задача упала
after('deploy:failed', 'deploy:unlock');
// ручной откат из CLI
./vendor/bin/dep rollback production
Rollback меняет симлинк на предыдущий релиз. Время: ~3 секунды.
📌 Итог
Deployer + symlink-стратегия + GitHub Actions = деплой без простоя, с историей релизов и откатом в одну команду. Больше никакого git pull руками на проде.
Библиотека пхпшника