Любой серьёзный веб-проект рано или поздно упирается в необходимость грамотного администрирования сервера. А когда проект растёт, ручные деплои и настройки превращаются в узкое место, которое тормозит разработку и увеличивает риск ошибок. Здесь на помощь приходит CI/CD — непрерывная интеграция и доставка, которые автоматизируют тестирование и развёртывание.
В этой статье мы разберём два ключевых направления:
- Практическое администрирование Linux — настройка бэкапов, мониторинг, работа с логами, автоматизация через cron, управление дисками и памятью.
- CI/CD — что это, как устроены пайплайны, настройка GitHub Actions и GitLab CI, автоматический деплой на сервер.
Мы сделаем акцент на практических примерах, чтобы вы могли сразу применить знания.
Часть 1. Практическое администрирование Linux
Администрирование сервера — это не только установка пакетов и настройка веб-сервера. Это постоянное наблюдение за состоянием системы, обеспечение сохранности данных, своевременное реагирование на сбои и планирование ресурсов. Рассмотрим ключевые задачи.
1. Резервное копирование (бэкапы)
Бэкапы — это ваша страховка от потери данных. Они должны быть регулярными, проверяемыми и храниться отдельно от основного сервера.
1.1 Бэкап файлов и баз данных
Самый простой способ — использовать tar и mysqldump с последующей архивацией.
Скрипт бэкапа для типового проекта:
#!/bin/bash
# backup.sh
# Директории для бэкапа
# Никогда не храните пароли в скриптах. Используйте переменные окружения или менеджер секретов!
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)
WEB_ROOT="/var/www/html"
DB_USER="root"
DB_PASSWORD="${DB_PASSWORD:-}"
if [ -z "$DB_PASSWORD" ]; then
echo "Ошибка: не задан DB_PASSWORD" >&2
exit 1
fi
DB_NAME="mydb"
# Создание папки для бэкапа, если её нет
mkdir -p $BACKUP_DIR
# Бэкап файлов
tar -czf "$BACKUP_DIR/files_$DATE.tar.gz" $WEB_ROOT
# Бэкап базы данных
mysqldump -u $DB_USER -p$DB_PASSWORD $DB_NAME > "$BACKUP_DIR/db_$DATE.sql"
# Архивация дампа (по желанию)
gzip "$BACKUP_DIR/db_$DATE.sql"
# Удаление старых бэкапов (старше 7 дней)
find $BACKUP_DIR -name "*.tar.gz" -type f -mtime +7 -delete
find $BACKUP_DIR -name "*.sql.gz" -type f -mtime +7 -delete
echo "Бэкап завершён: $DATE"Использование rsync для синхронизации с удалённым сервером:
# Синхронизация папки с бэкапами на удалённый сервер
rsync -avz --delete /backups/ user@backup-server:/backups/1.2 Автоматизация через cron
Добавьте скрипт в cron для ежедневного выполнения:
# Редактирование crontab
crontab -e
# Добавить строку (запуск каждый день в 2:00)
0 2 * * * /usr/local/bin/backup.sh > /var/log/backup.log 2>&11.3 Бэкап без остановки сервера
Для живых баз данных используйте репликацию или снимки (LVM, ZFS). Для MySQL можно использовать --single-transaction:
mysqldump --single-transaction -u root -p mydb > mydb.sqlЭто создаст согласованный дамп без блокировки таблиц.
🔍 Нюанс: --single-transaction работает только для таблиц InnoDB. Для MyISAM или смешанных движков лучше использовать репликацию или снапшоты (LVM/ZFS), иначе дамп может быть несогласованным.
2. Мониторинг сервера
Мониторинг нужен, чтобы вовремя заметить проблемы: переполнение диска, высокую нагрузку на CPU, нехватку памяти или аномалии в сети.
2.1 Базовый мониторинг из командной строки
Эти команды должны быть в арсенале каждого администратора:
# Нагрузка на процессор (load average) и процессы
top
htop # более удобный вариант
# Использование дисков
df -h
du -sh /var/* # размер папок
# Свободная память
free -m
# Сетевая статистика
iftop # или nethogs
# Открытые порты и соединения
netstat -tulpn
ss -tulpn
# Просмотр системных логов в реальном времени
tail -f /var/log/syslog
journalctl -f2.2 Простые инструменты мониторинга
- monit — лёгкий инструмент, который может перезапускать упавшие сервисы и отправлять уведомления.
- Netdata — красивые графики в реальном времени, устанавливается одной командой.
- Prometheus + Grafana — профессиональное решение для сбора метрик и визуализации.
Пример установки Netdata:
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# После установки открыть в браузере http://ваш_сервер:19999Не открывайте порт Netdata (19999) напрямую в интернет. Используйте обратный прокси или ограничьте доступ по IP.
2.3 Настройка оповещений
Настройте отправку уведомлений о проблемах через email или Telegram. В простейшем случае можно использовать скрипт, который проверяет занятость диска:
#!/bin/bash
# disk_alert.sh
THRESHOLD=80
USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $USAGE -gt $THRESHOLD ]; then
echo "Внимание! Занято $USAGE% диска" | mail -s "Alert: Disk full" admin@example.com
fiДобавьте в cron:
0 * * * * /usr/local/bin/disk_alert.sh3. Работа с системными логами
Логи — это глаза администратора. Они помогают расследовать сбои, атаки и проблемы производительности.
3.1 Основные логи
| Система | Лог-файл | Содержание |
|---|---|---|
| Linux | /var/log/syslog или /var/log/messages | Системные события |
| Авторизация | /var/log/auth.log | Входы в систему, sudo |
| Веб-сервер (Nginx) | /var/log/nginx/access.log, error.log | Запросы и ошибки |
| База данных | /var/log/mysql/error.log | Ошибки MySQL |
| PHP-FPM | /var/log/php8.1-fpm.log, slow.log | Ошибки и медленные запросы |
3.2 Настройка logrotate
Чтобы логи не разрастались бесконечно, используйте logrotate. Его конфигурация находится в /etc/logrotate.conf и /etc/logrotate.d/.
Пример для собственного приложения:
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 www-data www-data
postrotate
systemctl reload myapp
endscript
}Это будет ежедневно архивировать старые логи, хранить 7 последних файлов и перезагружать сервис после ротации.
Важно:
Сервис myapp должен реально существовать. Права на логи должны быть корректными (иначе сервис не сможет писать логи после create). Для веб‑сервера (Nginx/Apache) лучше использовать готовые конфиги из /etc/logrotate.d/nginx и т.д., а не писать с нуля.
3.3 Использование journalctl
В системах с systemd логи хранятся в журнале, доступном через journalctl:
# Просмотр всех логов с начала
journalctl
# Логи для конкретного сервиса
journalctl -u nginx
# Следование за логами
journalctl -f
# Логи за последний час
journalctl --since "1 hour ago"
# Фильтр по уровню ошибок
journalctl -p err4. Автоматизация задач с cron
cron — классический планировщик для выполнения периодических задач.
Синтаксис crontab:
* * * * * команда
│ │ │ │ │
│ │ │ │ └─── день недели (0-7, 0=воскресенье)
│ │ │ └───── месяц (1-12)
│ │ └─────── день месяца (1-31)
│ └───────── час (0-23)
└─────────── минута (0-59)
Примеры:
# Каждый день в 3:15
15 3 * * * /script/backup.sh
# Каждую минуту
* * * * * /script/check_status.sh
# Каждый час в 15 минут
15 * * * * /script/hourly.sh
# По выходным в 8:00
0 8 * * 0,6 /script/weekend.sh
# Каждые 5 минут
*/5 * * * * /script/five_min.shПолезные переменные в crontab:
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com5. Управление дисками и файловыми системами
Наполнение диска — одна из самых частых причин отказа сервера.
Проверка свободного места:
df -hПоиск самых больших файлов и папок:
# Топ-10 файлов в /var
find /var -type f -exec du -h {} + | sort -hr | head -10
# Команда рабочая, но на больших файловых системах может быть медленной и создавать много процессов. Альтернатива:
du -ah /var | sort -hr | head -20
# Размер папок в /var
du -sh /var/* | sort -hrОчистка временных файлов:
# Удаление старых файлов из /tmp (старше 7 дней)
find /tmp -type f -atime +7 -delete
# Очистка кеша apt (Debian/Ubuntu)
sudo apt clean
sudo apt autocleanНастройка мониторинга диска через cron и оповещения, как показано выше.
Часть 2. CI/CD — непрерывная интеграция и доставка
CI/CD — это практика автоматизации сборки, тестирования и развёртывания приложений. Она позволяет быстро и безопасно доставлять изменения пользователям, минимизируя человеческие ошибки.
1. Основные понятия
- CI (Continuous Integration) — непрерывная интеграция: автоматическая сборка и тестирование кода при каждом изменении в репозитории.
- CD (Continuous Delivery/Delivery) — непрерывная доставка: автоматический деплой на тестовые или стейджинг-окружения.
- CD (Continuous Deployment) — непрерывное развёртывание: автоматический деплой сразу в продакшен (при успешных тестах).
2. Как работает CI/CD пайплайн
Типичный пайплайн включает этапы:
- Pull/Push — разработчик пушит изменения в репозиторий.
- Build — сборка проекта (компиляция, установка зависимостей, сборка Docker-образа).
- Test — запуск тестов (юнит-тесты, интеграционные, линтеры).
- Deploy — развёртывание на сервер (или публикация образа в реестр).
3. Инструменты CI/CD
Сегодня популярны:
- GitHub Actions (встроен в GitHub, бесплатен для публичных репозиториев)
- GitLab CI (встроен в GitLab, очень гибкий)
- Jenkins (классика, но требует обслуживания)
- Bitbucket Pipelines, CircleCI, Travis CI и др.
Мы сосредоточимся на GitHub Actions и GitLab CI, как самых доступных.
4. GitHub Actions
GitHub Actions позволяет создавать пайплайны в виде YAML-файлов в папке .github/workflows/.
4.1 Простой пайплайн для проверки синтаксиса PHP
Создайте файл .github/workflows/ci.yml:
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
tools: composer
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Run PHP linter
run: composer run-script lint
- name: Run PHPUnit tests
run: vendor/bin/phpunitЭтот пайплайн запускается при каждом пуше или PR в ветки main/develop. Он проверяет синтаксис PHP и запускает тесты.
4.2 Сборка и публикация Docker-образа
name: Build and Push Docker Image
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: myuser/myapp:latest,${{ github.sha }}Значения DOCKER_USERNAME и DOCKER_TOKEN хранятся в настройках репозитория (Settings → Secrets → Actions) и никогда не должны попадать в код! Здесь мы используем секреты GitHub (настраиваются в настройках репозитория → Secrets) для логина в Docker Hub.
4.3 Автоматический деплой на сервер через SSH
name: Deploy to Production
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_KEY }}
script: |
cd /var/www/myapp
git pull origin main
composer install --no-dev
php artisan migrate --force
sudo systemctl reload nginx⚠️ Важно: Приватный SSH‑ключ должен иметь ограниченные права (только на деплой), не должен использоваться для интерактивного входа и не должен храниться в репозитории. Лучше создать отдельный ключ с ограниченным доступом и добавить его в CI/CD Secrets.
Этот пайплайн подключается к серверу, забирает изменения, обновляет зависимости и применяет миграции.
5. GitLab CI
GitLab CI использует файл .gitlab-ci.yml в корне репозитория.
5.1 Базовый пайплайн
stages:
- build
- test
- deploy
variables:
APP_ENV: test
cache:
paths:
- vendor/
before_script:
- apt-get update -qq && apt-get install -y -qq git
- composer install --prefer-dist --no-interaction
build:
stage: build
script:
- echo "Building..."
artifacts:
paths:
- vendor/
test:
stage: test
script:
- vendor/bin/phpunit
deploy:
stage: deploy
only:
- main
script:
- echo "Deploying to production..."
- ssh $DEPLOY_USER@$DEPLOY_HOST "cd /var/www/myapp && git pull && composer install --no-dev && sudo systemctl reload nginx"
environment:
name: production5.2 Использование Docker в GitLab CI
GitLab CI поддерживает запуск в контейнерах. Определите образ в начале:
image: php:8.1-cliА для более сложных задач можно использовать услугу services (например, MySQL для тестов).
services:
- mysql:8.0
variables:
DB_HOST: mysql
DB_DATABASE: test_db
DB_USER: root
DB_PASSWORD: rootВ реальных проектах используйте CI/CD Variables, а не хардкод паролей в .gitlab-ci.yml
6. Практические советы по CI/CD
6.1 Использование переменных окружения
Никогда не храните пароли и ключи в коде. Используйте встроенные механизмы секретов (GitHub Secrets, GitLab CI Variables).
6.2 Тестирование перед деплоем
Включите в пайплайн:
- Статический анализ кода (PHPStan, Psalm).
- Линтеры (ESLint для JS, PHPCS для PHP).
- Тесты безопасности (например,
composer audit).
6.3 Стратегии деплоя
- Rolling update — поочерёдное обновление серверов в кластере.
- Blue-green deployment — два окружения (blue и green), переключение трафика.
- Canary releases — выкатка на малую часть пользователей.
- Feature flags — включение нового функционала только для выбранных пользователей.
Для простых проектов достаточно обычного git pull и перезапуска сервисов.
6.4 Откат (rollback)
Обеспечьте возможность быстрого отката к предыдущей версии. При использовании Docker — достаточно запустить старый образ. При классическом деплое — храните бэкапы файлов и базы данных перед каждым обновлением.
6.5 Мониторинг после деплоя
Настройте уведомления и проверку работоспособности после деплоя. Например, скрипт проверяет, что сайт отвечает 200 OK:
curl -f https://example.com || (echo "Site is down!" && exit 1)Этот шаг можно добавить в пайплайн как финальную проверку.
7. Интеграция администрирования и CI/CD
Теперь свяжем воедино обе части нашего руководства. Грамотный администратор использует CI/CD для автоматизации рутинных задач:
- Автоматические бэкапы — запускаются по cron, но их состояние можно проверять в пайплайне.
- Мониторинг — настройка оповещений о сбоях, которые могут быть обработаны автоматически (например, перезапуск контейнера).
- Обновление ПО — например, автоматическая сборка и деплой обновлённого образа при обнаружении новой версии базового образа.
Пример комплексного подхода:
- Разработчик пушит код → запускается CI (сборка, тесты, линтеры).
- При успехе создаётся Docker-образ и загружается в реестр.
- На сервере работает скрипт (запускаемый через cron или webhook), который проверяет наличие нового образа и обновляет контейнер.
- После деплоя система мониторинга проверяет, что сервис работает, и отправляет уведомление администратору.
Этот процесс минимизирует человеческий фактор и ускоряет релизы.
Заключение
Мы прошли путь от базовых задач администрирования до полностью автоматизированного пайплайна:
- Научились делать бэкапы и автоматизировать их через cron.
- Освоили мониторинг и работу с логами — глаза и уши сервера.
- Разобрались с cron и управлением дисками.
- Узнали, что такое CI/CD, как работают GitHub Actions и GitLab CI.
- Встроили деплой в пайплайн и связали его с административными задачами.
Теперь вы можете не только поддерживать сервер в рабочем состоянии, но и автоматизировать развёртывание, делая процесс разработки и доставки быстрым, надёжным и предсказуемым. Эти навыки — основа для работы с современными проектами любого масштаба.
