Восстановление сайта после сбоя
Восстановление — стрессовый процесс, который должен быть спланирован заранее. Наличие runbook с чёткими шагами сокращает время восстановления в 3–5 раз по сравнению с диагностикой на ходу.
Классификация сбоев и первые действия
Сайт недоступен (HTTP 5xx или timeout):
# 1. Проверяем сервис
systemctl status nginx php8.2-fpm
# 2. Перезапуск если завис
sudo systemctl restart php8.2-fpm
sudo systemctl restart nginx
# 3. Смотрим логи
journalctl -u nginx -n 100 --no-pager
tail -100 /var/log/php8.2-fpm.log
Переполнен диск:
df -h # находим заполненный раздел
du -sh /var/log/* | sort -rh | head -10 # где место
# Очистка логов
truncate -s 0 /var/log/nginx/access.log
journalctl --vacuum-size=100M
# Очистка Docker
docker system prune -f
OOM (Out of Memory):
dmesg | grep -i "out of memory"
# Увеличить swap (временное решение)
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
Упала база данных:
# PostgreSQL
sudo systemctl restart postgresql
# Проверка логов
tail -50 /var/log/postgresql/postgresql-14-main.log
# Если повреждены файлы — восстановление из бэкапа
Восстановление из бэкапа: пошагово
# 1. Определяем последний рабочий бэкап
aws s3 ls s3://my-backups/database/ | tail -5
# 2. Скачиваем
aws s3 cp s3://my-backups/database/mysite_20241201_060000.dump.gz /tmp/
# 3. Создаём новую БД (старую не трогаем — сначала тестируем)
createdb mysite_restored
gunzip < /tmp/mysite_20241201_060000.dump.gz | pg_restore -d mysite_restored --no-owner
# 4. Проверяем целостность
psql -d mysite_restored -c "SELECT COUNT(*) FROM users;"
psql -d mysite_restored -c "SELECT MAX(created_at) FROM orders;"
# 5. Переключаем приложение на восстановленную БД
# Меняем DB_NAME в .env
# Перезапускаем приложение
# 6. Переименовываем БД (если подходит)
# ALTER DATABASE mysite RENAME TO mysite_broken;
# ALTER DATABASE mysite_restored RENAME TO mysite;
Восстановление файлов
# Восстановление uploads/ из S3
aws s3 sync s3://my-backups/files/ /var/www/mysite/storage/app/public/ \
--exact-timestamps
# Права после восстановления
chown -R www-data:www-data /var/www/mysite/storage/
chmod -R 755 /var/www/mysite/storage/
Rollback кода
# Через Git
git log --oneline -10 # находим рабочий коммит
git checkout <commit-hash>
# или
git revert <bad-commit>
# Через Docker (если используется)
docker pull myregistry/myapp:previous-tag
docker stop myapp
docker run -d --name myapp myregistry/myapp:previous-tag
Runbook template
## Runbook: Восстановление после полного отказа
**Условие:** сайт недоступен более 5 минут
### Шаг 1: Диагностика (5 мин)
- [ ] `ssh deploy@server`
- [ ] `systemctl status nginx php-fpm mysql`
- [ ] `df -h` — проверка диска
- [ ] `free -m` — проверка памяти
### Шаг 2: Быстрое восстановление (5–10 мин)
- [ ] Перезапуск сервисов
- [ ] Если нет — восстановление из бэкапа (см. раздел выше)
### Шаг 3: Уведомления
- [ ] Slack: #incidents — статус инцидента
- [ ] Статус-страница — incident created
### Шаг 4: Постмортем
- [ ] RCA в течение 24 часов после восстановления
Время восстановления с подготовленным runbook и актуальными бэкапами: 30 мин – 2 часа.







