PurpleSchool — курсы программирования онлайн
  • Пути
    • Frontend React разработчик
    • Frontend Vue разработчик
    • Backend разработчик Node.js
    • Fullstack разработчик React / Node.js
    • Mobile разработчик React Native
    • Backend разработчик Golang
    • Devops инженер
    • Backend разработчик Python
  • AI для кодаНовое
  • О нас
    • Отзывы
    • Реферальная программа
    • О компании
    • Контакты
  • Иконка открытия меню
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
PurpleSchool — платформа бесплатных roadmap и курсов для разработчиков
ютуб иконка
Telegram иконка
VK иконка
VK иконка
Курсы
ГлавнаяКаталог курсовFrontendBackendFullstack
Практика
КарьераПроектыPurpleПлюс
Материалы
БлогБаза знаний
Документы
Договор офертаПолитика конфиденциальностиПроверка сертификатаМиграция курсовРеферальная программа
Реквизиты
ИП Ларичев Антон АндреевичИНН 773373765379contact@purpleschool.ru

PurpleSchool © 2020 -2026 Все права защищены

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развитияВопросы для собеседований
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • PurpleSchool — курсы программирования онлайн
    • AI для кодаНовое
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    Как настроить CI/CD пайплайн с нуля: полное руководство

    Как настроить CI/CD пайплайн с нуля: полное руководство

    Аватар автора Как настроить CI/CD пайплайн с нуля: полное руководство

    Антон Ларичев

    Иконка календаря14 октября 2026
    CI/CDDevOpsGitHub ActionsDockerавтоматизацияmiddleИконка уровня middle
    Картинка поста Как настроить CI/CD пайплайн с нуля: полное руководство

    Введение

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

    В этой статье разберём, как построить CI/CD пайплайн с нуля на примере GitHub Actions — самого доступного инструмента, который не требует отдельной инфраструктуры. Логика переносится на GitLab CI, Jenkins или CircleCI почти без изменений, меняется только синтаксис конфигурации.

    Шаг 1: Структура репозитория и первый workflow

    GitHub Actions ищет конфигурации в папке .github/workflows. Начнём с простейшего файла, который запускается при пуше в ветку main.

    # .github/workflows/ci.yml
    name: CI
    
    on:
      push:
        branches: [main]
      pull_request:
        branches: [main]
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - name: Клонируем репозиторий
            uses: actions/checkout@v4
    
          - name: Устанавливаем Node.js
            uses: actions/setup-node@v4
            with:
              node-version: '20'
              cache: 'npm'
    
          - name: Устанавливаем зависимости
            run: npm ci
    

    Триггер on описывает, когда запускать пайплайн. Важно указывать и push, и pull_request — так проверка кода идёт ещё до слияния в основную ветку, а не после.

    Шаг 2: Добавляем линтер и тесты

    Пайплайн без тестов — это просто автоматическая сборка, а не полноценный CI. Добавим шаги проверки.

          - name: Линтер
            run: npm run lint
    
          - name: Юнит-тесты
            run: npm run test -- --coverage
    
          - name: Сборка проекта
            run: npm run build
    

    Если любой из шагов завершится с ошибкой, GitHub Actions остановит выполнение и пометит коммит крестиком. Это тот самый сигнал, который не даёт сломанному коду попасть в main.

    Для больших проектов стоит разделить джобы, чтобы линтер и тесты выполнялись параллельно, а не последовательно:

    jobs:
      lint:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: npm ci
          - run: npm run lint
    
      test:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: npm ci
          - run: npm run test
    

    Параллельные джобы сокращают время прогона пайплайна почти вдвое на средних проектах.

    Шаг 3: Сборка и публикация Docker-образа

    Когда тесты зелёные, можно собирать образ и пушить его в registry. Добавим джобу, которая зависит от успешного прохождения тестов через needs.

      docker:
        needs: [lint, test]
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
    
          - name: Логинимся в Docker Hub
            uses: docker/login-action@v3
            with:
              username: ${{ secrets.DOCKERHUB_USERNAME }}
              password: ${{ secrets.DOCKERHUB_TOKEN }}
    
          - name: Собираем и пушим образ
            uses: docker/build-push-action@v5
            with:
              context: .
              push: true
              tags: myorg/myapp:${{ github.sha }}
    

    Тег с github.sha даёт уникальную версию образа под каждый коммит — это упрощает откат на предыдущую версию, если что-то пойдёт не так после деплоя.

    Шаг 4: Автоматический деплой

    Финальный шаг — доставка образа на сервер. Самый простой вариант для небольшого проекта — подключиться по SSH и перезапустить контейнер.

      deploy:
        needs: docker
        runs-on: ubuntu-latest
        if: github.ref == 'refs/heads/main'
        steps:
          - name: Деплой на сервер по SSH
            uses: appleboy/ssh-action@v1
            with:
              host: ${{ secrets.SERVER_HOST }}
              username: ${{ secrets.SERVER_USER }}
              key: ${{ secrets.SERVER_SSH_KEY }}
              script: |
                docker pull myorg/myapp:${{ github.sha }}
                docker stop myapp || true
                docker rm myapp || true
                docker run -d --name myapp -p 3000:3000 myorg/myapp:${{ github.sha }}
    

    Условие if: github.ref == 'refs/heads/main' защищает от случайного деплоя из feature-веток. Для продакшн-сценариев вместо прямого SSH лучше использовать Kubernetes, но для старта такого подхода достаточно.

    Шаг 5: Секреты и переменные окружения

    Никогда не храните пароли, токены и ключи прямо в yaml-файле. GitHub Actions хранит их в разделе Settings → Secrets and variables → Actions, а в конфигурации они доступны через secrets.ИМЯ.

    Для переменных, которые не являются секретными (например, окружение staging или production), используйте vars вместо secrets — это упрощает чтение логов при отладке.

    Частые ошибки

    Отсутствие кеширования зависимостей. Без cache: 'npm' в setup-node каждый запуск заново скачивает все пакеты, что добавляет минуты к каждому пайплайну.

    Одна гигантская джоба вместо нескольких параллельных. Это увеличивает время обратной связи и усложняет диагностику — непонятно, что именно упало: линтер, тесты или сборка.

    Деплой без проверки тестов. Джоба deploy обязательно должна зависеть через needs от джобы с тестами, иначе сломанный код может уехать в прод при зелёной сборке Docker-образа.

    Хранение секретов в коде или в yaml-файле пайплайна. Даже в приватном репозитории это риск — токены попадают в историю git и остаются там навсегда.

    Игнорирование уведомлений о падении пайплайна. Если команда привыкла игнорировать красные билды, CI/CD теряет смысл — стоит настроить уведомления в Slack или Telegram через дополнительный шаг.

    Отсутствие стратегии отката. Если у образов нет версионирования по тегам, откат на предыдущую рабочую версию превращается в ручной поиск по истории сборок.

    Заключение

    CI/CD пайплайн с нуля строится по одной и той же схеме: проверка кода, тесты, сборка, деплой. Начать стоит с малого — линтера и тестов на каждый пуш, а затем постепенно добавлять сборку Docker-образа и автоматический деплой.

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

    Иконка глаза7

    Комментарии

    0

    Постройте личный план изучения Vue.js 3, Vue Router и Pinia до уровня Middle — бесплатно!

    Vue.js 3, Vue Router и Pinia — часть карты развития Frontend

    • step100+ шагов развития
    • lessons30 бесплатных лекций
    • lessons300 бонусных рублей на счет

    Бесплатные лекции

    Лучшие курсы по теме

    изображение курса

    Angular

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.6
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Nuxt

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга5.0
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    Feature-Sliced Design

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.6
    3 999 ₽ 6 990 ₽
    Подробнее

    Похожие статьи

    Картинка поста CLAUDE.md: как написать инструкции для Claude Code
    Иконка аватараАнтон
    Иконка календаря11 октября 2026
    AI-инструментыClaude CodeDevOps+ 1middleИконка уровня middle

    CLAUDE.md: как написать инструкции для Claude Code

    CLAUDE.md — это файл с инструкциями по проекту, который Claude Code читает в начале каждой сессии. Положите его в корень репозитория и опишите внутри, чем проект собирается, чем запускаются тесты и каких соглашений держаться в коде. После этого агент перестанет спрашивать одно и то же в каждом новом диалоге и предлагать решения, которые в вашей кодовой базе не приняты. Формат предельно простой: обычный Markdown, обязательных полей нет, заголовки любые. Дальше — где именно создавать файл и как Claude Code собирает инструкции сразу из нескольких мест, что писать внутрь, как подключать к файлу другие документы и чем CLAUDE.md отличается от AGENTS.md. Одна оговорка перед началом: Claude Code обновляется часто, набор команд и поддерживаемых файлов пополняется. Если какая-то деталь ниже ведёт себя у вас иначе, сверяйтесь с документацией той версии, которая стоит у вас.

    Иконка чипа0
    Иконка глаза191
    Иконка комментариев0
    Иконка аватараАнтон
    Иконка календаря10 октября 2026
    AI-инструментыClaude CodeDevOps+ 2middleИконка уровня middle

    Агенты в OpenCode: как создать своего агента

    Агент в OpenCode — это именованный профиль работы: своя модель, свой системный промпт и свой список разрешённых инструментов. Чтобы создать своего агента, нужно описать его отдельным markdown-файлом в папке `.opencode/agent/` внутри проекта (или в `~/.config/opencode/agent/`, если агент нужен во всех проектах) либо объявить его в блоке `agent` файла `opencode.json`. После этого агент появляется в списке доступных, и его можно вызвать прямо в сессии.

    Иконка чипа0
    Иконка глаза283
    Иконка комментариев0
    Картинка поста OpenCode Desktop: установка и подключение Claude
    Иконка аватараАнтон
    Иконка календаря09 октября 2026
    AI-инструментыDevOpsopenai+ 2middleИконка уровня middle

    OpenCode Desktop: установка и подключение Claude

    OpenCode Desktop — графическое приложение OpenCode: тот же агент, что работает в терминале, но с оконным интерфейсом. Скачивается и ставится оно в России штатно, а вот подключить к нему Claude с первой попытки не выйдет, и дело не в блокировках: встроенная форма добавления своего провайдера в приложении не работает и отвечает ошибкой на любые данные. Рабочий путь — описать провайдера в opencode.json руками. Готовый OpenAI-совместимый эндпоинт с оплатой рублями даёт AI для кода от PurpleSchool. Ниже — установка OpenCode Desktop на macOS, Windows и Linux, разбор ошибки и конфиг целиком.

    Иконка чипа0
    Иконка глаза307
    Иконка комментариев0
    Иконка чипа0