Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Senior: питання на співбесіді з теми «Деплой і DevOps»

Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.

4 питання

Деплой без простою: користувачі весь час бачать робочу версію.

Atomic (symlink) deploy - кожен реліз клонується в нову папку, там встановлюються залежності й збираються ассети, після чого current атомарно перемикається через symlink:

releases/2026_06_05_120000/ ← новий
current → releases/... ← атомарне перемикання

Кроки на деплої: composer install --no-dev, npm run build, migrate --force, кеш конфіг/маршрутів, перезапуск воркерів (queue:restart) і OPcache.

Інструменти: Envoyer, Deployer, CI/CD-пайплайни, Kubernetes (rolling update). Окрема увага - сумісність міграцій із попередньою версією коду під час перемикання.

Докладніше в документації: Деплой

CI автоматично перевіряє кожен пуш, CD - автоматично доставляє код.

Типовий пайплайн (GitHub Actions / GitLab CI):

- composer install
- vendor/bin/pint --test # стиль
- vendor/bin/phpstan analyse # статичний аналіз
- php artisan test --parallel # тести
- npm ci && npm run build # ассети
# → деплой при успіху

Деплой: SSH-скрипт, Docker-образ у реєстрі + rolling update у Kubernetes, або сервіси на кшталт Forge/Envoyer. На етапі деплою - migrate --force, кешування конфіга/маршрутів, queue:restart. CI/CD дає швидкий зворотний зв'язок і знижує ризик людської помилки при релізі.

Докладніше в документації: Деплой

За замовчуванням php artisan down створює файл у storage/framework - лише на тому сервері, де виконали команду. На п'яти серверах решта чотири продовжать приймати запити.

Драйвер на основі кешу:

APP_MAINTENANCE_DRIVER=cache
APP_MAINTENANCE_STORE=redis

Сховище має бути спільним для всіх серверів - тоді досить одного down.

Корисні опції:

php artisan down --secret="team-preview" --render="errors::503" --retry=60
  • --secret - команда відкриває https://example.com/team-preview і бачить сайт через cookie обходу;
  • --render - сторінку віддають до завантаження фреймворку, тож вона не впаде під час composer install;
  • --retry - заголовок Retry-After для клієнтів і пошукових ботів;
  • --redirect=/ - перенаправляти всі запити.

Черги: поки застосунок у режимі обслуговування, воркери не обробляють завдання - вони накопичуються й виконаються після up. Довге обслуговування - велика черга на виході; варто оцінити, чи витримають її воркери, і чи не застаріють завдання (листи «ваш код дійсний 10 хвилин»).

Планувальник теж не запускає завдання, окрім evenInMaintenanceMode().

Для деплою без простою режим обслуговування взагалі не потрібен - його залишають для робіт, що справді вимагають зупинки.

Докладніше в документації: Режим обслуговування на кількох серверах

Журнал корисний, лише якщо за ним можна відновити, що сталося з конкретним запитом чи завданням.

1. Контекст у кожному записі:

// middleware
Context::add('request_id', (string) Str::uuid());
Context::add('user_id', $request->user()?->id);

Log::info('Замовлення оформлено', ['order_id' => $order->id]);

Дані з Context автоматично додаються до кожного запису журналу й передаються в завдання черги, які цей запит поставив. Тоді один request_id зв'язує запит, завдання й виклики API.

2. Структурований формат - JSON (JsonFormatter) замість рядків, щоб журнал фільтрувався в Loki, ELK чи Datadog за полями.

3. Рівні з розумом: error - те, що вимагає уваги; warning - підозріле, але оброблене; info - бізнес-події; debug - вимкнений на продакшені. Якщо все error, сигнал губиться.

4. Канали: stack з кількох каналів - stderr для платформи, окремий канал для платежів, Slack лише для critical.

5. Винятки - у сервіс відстеження помилок (Sentry, Flare, Nightwatch) з групуванням і стектрейсом; throttle() у withExceptions(), щоб шторм однакових помилок не з'їв квоту.

Чого не писати: паролі, токени, повні номери карток, персональні дані без потреби. Витік журналу - теж витік.

Локально журнал зручно читати через php artisan pail з фільтрами за рівнем і користувачем.

Докладніше в документації: Контекстна інформація