Практическое администрирование Linux и CI/CD: от основ до автоматизации

Любой серьёзный веб-проект рано или поздно упирается в необходимость грамотного администрирования сервера. А когда проект растёт, ручные деплои и настройки превращаются в узкое место, которое тормозит разработку и увеличивает риск ошибок. Здесь на помощь приходит CI/CD — непрерывная интеграция и доставка, которые автоматизируют тестирование и развёртывание.

В этой статье мы разберём два ключевых направления:

  • Практическое администрирование Linux — настройка бэкапов, мониторинг, работа с логами, автоматизация через cron, управление дисками и памятью.
  • CI/CD — что это, как устроены пайплайны, настройка GitHub Actions и GitLab CI, автоматический деплой на сервер.

Мы сделаем акцент на практических примерах, чтобы вы могли сразу применить знания.

Часть 1. Практическое администрирование Linux

Администрирование сервера — это не только установка пакетов и настройка веб-сервера. Это постоянное наблюдение за состоянием системы, обеспечение сохранности данных, своевременное реагирование на сбои и планирование ресурсов. Рассмотрим ключевые задачи.

1. Резервное копирование (бэкапы)

Бэкапы — это ваша страховка от потери данных. Они должны быть регулярными, проверяемыми и храниться отдельно от основного сервера.

1.1 Бэкап файлов и баз данных

Самый простой способ — использовать tar и mysqldump с последующей архивацией.

Скрипт бэкапа для типового проекта:

Bash
#!/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 для синхронизации с удалённым сервером:

Bash
# Синхронизация папки с бэкапами на удалённый сервер
rsync -avz --delete /backups/ user@backup-server:/backups/

1.2 Автоматизация через cron

Добавьте скрипт в cron для ежедневного выполнения:

Bash
# Редактирование crontab
crontab -e

# Добавить строку (запуск каждый день в 2:00)
0 2 * * * /usr/local/bin/backup.sh > /var/log/backup.log 2>&1

1.3 Бэкап без остановки сервера

Для живых баз данных используйте репликацию или снимки (LVM, ZFS). Для MySQL можно использовать --single-transaction:

Bash
mysqldump --single-transaction -u root -p mydb > mydb.sql

Это создаст согласованный дамп без блокировки таблиц.

🔍 Нюанс: --single-transaction работает только для таблиц InnoDB. Для MyISAM или смешанных движков лучше использовать репликацию или снапшоты (LVM/ZFS), иначе дамп может быть несогласованным.

2. Мониторинг сервера

Мониторинг нужен, чтобы вовремя заметить проблемы: переполнение диска, высокую нагрузку на CPU, нехватку памяти или аномалии в сети.

2.1 Базовый мониторинг из командной строки

Эти команды должны быть в арсенале каждого администратора:

Bash
# Нагрузка на процессор (load average) и процессы
top
htop   # более удобный вариант

# Использование дисков
df -h
du -sh /var/*   # размер папок

# Свободная память
free -m

# Сетевая статистика
iftop   # или nethogs

# Открытые порты и соединения
netstat -tulpn
ss -tulpn

# Просмотр системных логов в реальном времени
tail -f /var/log/syslog
journalctl -f

2.2 Простые инструменты мониторинга

  • monit — лёгкий инструмент, который может перезапускать упавшие сервисы и отправлять уведомления.
  • Netdata — красивые графики в реальном времени, устанавливается одной командой.
  • Prometheus + Grafana — профессиональное решение для сбора метрик и визуализации.

Пример установки Netdata:

Bash
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# После установки открыть в браузере http://ваш_сервер:19999

Не открывайте порт Netdata (19999) напрямую в интернет. Используйте обратный прокси или ограничьте доступ по IP.

2.3 Настройка оповещений

Настройте отправку уведомлений о проблемах через email или Telegram. В простейшем случае можно использовать скрипт, который проверяет занятость диска:

Bash
#!/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:

Bash
0 * * * * /usr/local/bin/disk_alert.sh

3. Работа с системными логами

Логи — это глаза администратора. Они помогают расследовать сбои, атаки и проблемы производительности.

3.1 Основные логи

СистемаЛог-файлСодержание
Linux/var/log/syslog или /var/log/messagesСистемные события
Авторизация/var/log/auth.logВходы в систему, sudo
Веб-сервер (Nginx)/var/log/nginx/access.logerror.logЗапросы и ошибки
База данных/var/log/mysql/error.logОшибки MySQL
PHP-FPM/var/log/php8.1-fpm.logslow.logОшибки и медленные запросы

3.2 Настройка logrotate

Чтобы логи не разрастались бесконечно, используйте logrotate. Его конфигурация находится в /etc/logrotate.conf и /etc/logrotate.d/.

Пример для собственного приложения:

Bash
# /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:

Bash
# Просмотр всех логов с начала
journalctl

# Логи для конкретного сервиса
journalctl -u nginx

# Следование за логами
journalctl -f

# Логи за последний час
journalctl --since "1 hour ago"

# Фильтр по уровню ошибок
journalctl -p err

4. Автоматизация задач с cron

cron — классический планировщик для выполнения периодических задач.

Синтаксис crontab:

* * * * * команда
│ │ │ │ │
│ │ │ │ └─── день недели (0-7, 0=воскресенье)
│ │ │ └───── месяц (1-12)
│ │ └─────── день месяца (1-31)
│ └───────── час (0-23)
└─────────── минута (0-59)

Примеры:

Bash
# Каждый день в 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:

Bash
SHELL=/bin/bash
PATH=/usr/local/bin:/usr/bin:/bin
MAILTO=admin@example.com

5. Управление дисками и файловыми системами

Наполнение диска — одна из самых частых причин отказа сервера.

Проверка свободного места:

Bash
df -h

Поиск самых больших файлов и папок:

Bash
# Топ-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

Очистка временных файлов:

Bash
# Удаление старых файлов из /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 пайплайн

Типичный пайплайн включает этапы:

  1. Pull/Push — разработчик пушит изменения в репозиторий.
  2. Build — сборка проекта (компиляция, установка зависимостей, сборка Docker-образа).
  3. Test — запуск тестов (юнит-тесты, интеграционные, линтеры).
  4. Deploy — развёртывание на сервер (или публикация образа в реестр).

3. Инструменты CI/CD

Сегодня популярны:

  • GitHub Actions (встроен в GitHub, бесплатен для публичных репозиториев)
  • GitLab CI (встроен в GitLab, очень гибкий)
  • Jenkins (классика, но требует обслуживания)
  • Bitbucket PipelinesCircleCITravis CI и др.

Мы сосредоточимся на GitHub Actions и GitLab CI, как самых доступных.

4. GitHub Actions

GitHub Actions позволяет создавать пайплайны в виде YAML-файлов в папке .github/workflows/.

4.1 Простой пайплайн для проверки синтаксиса PHP

Создайте файл .github/workflows/ci.yml:

YAML
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-образа

YAML
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

YAML
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 Базовый пайплайн

YAML
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: production

5.2 Использование Docker в GitLab CI

GitLab CI поддерживает запуск в контейнерах. Определите образ в начале:

YAML
image: php:8.1-cli

А для более сложных задач можно использовать услугу services (например, MySQL для тестов).

YAML
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:

Bash
curl -f https://example.com || (echo "Site is down!" && exit 1)

Этот шаг можно добавить в пайплайн как финальную проверку.

7. Интеграция администрирования и CI/CD

Теперь свяжем воедино обе части нашего руководства. Грамотный администратор использует CI/CD для автоматизации рутинных задач:

  • Автоматические бэкапы — запускаются по cron, но их состояние можно проверять в пайплайне.
  • Мониторинг — настройка оповещений о сбоях, которые могут быть обработаны автоматически (например, перезапуск контейнера).
  • Обновление ПО — например, автоматическая сборка и деплой обновлённого образа при обнаружении новой версии базового образа.

Пример комплексного подхода:

  1. Разработчик пушит код → запускается CI (сборка, тесты, линтеры).
  2. При успехе создаётся Docker-образ и загружается в реестр.
  3. На сервере работает скрипт (запускаемый через cron или webhook), который проверяет наличие нового образа и обновляет контейнер.
  4. После деплоя система мониторинга проверяет, что сервис работает, и отправляет уведомление администратору.

Этот процесс минимизирует человеческий фактор и ускоряет релизы.

Заключение

Мы прошли путь от базовых задач администрирования до полностью автоматизированного пайплайна:

  • Научились делать бэкапы и автоматизировать их через cron.
  • Освоили мониторинг и работу с логами — глаза и уши сервера.
  • Разобрались с cron и управлением дисками.
  • Узнали, что такое CI/CD, как работают GitHub Actions и GitLab CI.
  • Встроили деплой в пайплайн и связали его с административными задачами.

Теперь вы можете не только поддерживать сервер в рабочем состоянии, но и автоматизировать развёртывание, делая процесс разработки и доставки быстрым, надёжным и предсказуемым. Эти навыки — основа для работы с современными проектами любого масштаба.