Есть знания, которые можно получить по учебнику. А есть те, которые впечатываются в память через настоящий провал — через ночные часы и сообщения "deploy failed" в три часа ночи.
Мой первый опыт с CI/CD — из второй категории.
Что я хотела автоматизировать
Небольшой веб-проект: VPS, GitHub, фронтенд на Node.js. Пуш в main — и код автоматически билдится, тесты проходятся, файлы улетают на сервер. Без ручных ssh-подключений и "а ты не забыла запустить сборку?". Казалось, задача на пару часов максимум.
Базовая структура:
- GitHub как репозиторий
- VPS как сервер
- Rsync для передачи файлов
- GitHub Actions как оркестратор
Первая попытка: build-скрипт
Начала с простого bash-скрипта. Установить зависимости, собрать проект, запушить на сервер. Скрипт работал — пока я запускала его вручную из терминала. Но хотелось автоматизации. Очевидный следующий шаг — GitHub Actions.
Второй заход: GitHub Actions
Написала вполне разумный workflow:
on: push to main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: npm install && npm run build
- name: Deploy
run: rsync -avz --delete dist/ user@server:/var/www/app/
Выглядело логично. На бумаге — идеально. В реальности первый же пуш показал все подводные камни.
Ошибка 1: rsync не установлен на runner
Первый же раннер GitHub Actions сообщил: "rsync: command not found". Как — не установлен? В моём терминале он есть, а в облаке — нет. ubuntu-latest это минимальный образ, без rsync.
Исправление: добавить шаг установки apt-get install rsync перед деплоем.
Ошибка 2: SSH-ключи и known_hosts
Дальше — попытка подключиться к серверу по SSH. Failed: "Host key verification failed". GitHub Actions runner не знает мой сервер. Пришлось добавить его в known_hosts.
Исправление:
- name: Add server to known_hosts
run: |
ssh-keyscan -H $SERVER_IP >> ~/.ssh/known_hosts
env:
SERVER_IP: ${{ secrets.SERVER_IP }}
Ошибка 3: Rsync и права
Снова failed. Rsync не мог удалить файлы на сервере — не хватало прав записи. Я использовала пользователя deploy, но права на папку принадлежали www-data.
Исправление: chown -R deploy:www-data /var/www/app и выставить правильные права на папку.
Ошибка 4: Артефакты между шагами
С шестой попытки workflow наконец прошёл. Но оказалось, что артефакты после билда не сохраняются между шагами — каждый шаг запускается в чистой среде. Мой собранный проект исчез.
Исправление: использовать actions/upload-artifact и actions/download-artifact для сохранения результата билда между шагами.
Что я поняла в итоге
Четыре вещи, которые я усвоила после этого опыта:
1. Rsync в GitHub Actions — не тривиальная задача. Лучше использовать готовые экшены типа appleboy/scp-action или easingthemes/ssh-deploy. Они решают все грабли с SSH и known_hosts за тебя.
2. Права на сервере нужно настраивать до первого деплоя. Не после. Создать пользователя, добавить в группу www-data, выставить umask так, чтобы файлы создавались с нужными правами.
3. Тесты — до деплоя. Звучит очевидно. Но у меня сначала деплоилось, потом CI/CD сламывался на этапе тестов. Я откатывала деплой, правила тесты, пушила снова. Лучше один раз поставить тесты в начало пайплайна.
4. Отдельная ветка для staging. Пушить напрямую в main и сразу деплоить на production — плохая практика. Правильно: пуш в develop → автодеплой на staging → пуш в main → ручное подтверждение или автодеплой на production.
Итоговый рабочий пайплайн
Вот что в итоге работает надёжно:
- actions/checkout
- setup-node
- npm ci && npm run build
- npm test (критично — до деплоя)
- upload-artifact
- appleboy/scp-action с приватным ключом из secrets
Звучит просто. Но между "звучит просто" и "работает надёжно" — четыре часа отладки, три сломанных деплоя и много нервных сообщений в чат.
Теперь я каждый раз настраиваю CI/CD с нуля — и каждый раз это занимает не пять часов, а час. Потому что все грабли уже встретила.
DevOps учат не книги. Его учат failure-режимы. Хорошая новость: каждый сломанный деплой — это одна новая строка в резюме.
Комментарии
Пока нет комментариев. Стань первым!