Drone CI: лёгкий CI/CD на Docker для небольших команд

Зачем нужен Drone CI и чем он отличается от Jenkins

Drone CI — это контейнерная система непрерывной интеграции, где каждый шаг пайплайна выполняется в изолированном Docker-контейнере. В отличие от Jenkins с его громоздкой Java-архитектурой и плагинами, Drone минималистичен: один бинарник, конфигурация через YAML, нативная поддержка Docker. Для команд из 5-20 разработчиков Drone часто оказывается идеальным выбором — он прост в установке, не требует постоянного обслуживания и потребляет минимум ресурсов.

Ключевые преимущества Drone CI:

  • Контейнерная изоляция — каждый шаг запускается в чистом контейнере, нет проблем с конфликтами зависимостей
  • Конфигурация как код — пайплайн описан в .drone.yml рядом с кодом проекта
  • Нативная интеграция с Git — поддержка GitHub, GitLab, Gitea, Bitbucket из коробки
  • Минимальные ресурсы — сервер потребляет ~50 МБ RAM в idle

Установка Drone Server и Runner

Drone состоит из двух компонентов: Server (API и веб-интерфейс) и Runner (исполнитель пайплайнов). Развернём оба через Docker Compose с подключением к Gitea — популярному self-hosted Git-серверу.

Подготовка OAuth-приложения в Gitea

Перед установкой Drone создайте OAuth2-приложение в Gitea для авторизации:

  1. Войдите в Gitea под администратором
  2. Перейдите в «Site Administration → Applications»
  3. Создайте приложение с Redirect URI: https://drone.example.com/login
  4. Сохраните Client ID и Client Secret

Сгенерируйте общий секрет для связи Server и Runner:

openssl rand -hex 16
# Пример: 9c4f2e8a1b3d5f7e0a2c4b6d8e0f1a3c

Docker Compose для Drone

Создайте файл docker-compose.yml:

version: "3.8"
services:
  drone-server:
    image: drone/drone:2
    restart: always
    ports:
      - "3001:80"
    environment:
      DRONE_GITEA_SERVER: https://gitea.example.com
      DRONE_GITEA_CLIENT_ID: ваш-client-id
      DRONE_GITEA_CLIENT_SECRET: ваш-client-secret
      DRONE_RPC_SECRET: 9c4f2e8a1b3d5f7e0a2c4b6d8e0f1a3c
      DRONE_SERVER_HOST: drone.example.com
      DRONE_SERVER_PROTO: https
      DRONE_DATABASE_DRIVER: sqlite3
      DRONE_DATABASE_DATASOURCE: /data/database.sqlite
      DRONE_USER_CREATE: username:admin,admin:true
    volumes:
      - drone-data:/data

  drone-runner:
    image: drone/drone-runner-docker:1
    restart: always
    environment:
      DRONE_RPC_PROTO: http
      DRONE_RPC_HOST: drone-server
      DRONE_RPC_SECRET: 9c4f2e8a1b3d5f7e0a2c4b6d8e0f1a3c
      DRONE_RUNNER_CAPACITY: 4
      DRONE_RUNNER_NAME: runner-01
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

volumes:
  drone-data:

Параметр DRONE_RUNNER_CAPACITY=4 позволяет выполнять до 4 пайплайнов параллельно. На сервере с 4+ ядрами и 8+ ГБ RAM это оптимальное значение.

Написание .drone.yml пайплайна

Пайплайн Drone описывается в файле .drone.yml в корне репозитория. Каждый pipeline содержит шаги (steps), которые выполняются последовательно в Docker-контейнерах с общим volume.

Пример пайплайна для Python-проекта

Типичный CI-пайплайн для Django-приложения с тестами и деплоем:

kind: pipeline
type: docker
name: default

steps:
  - name: install
    image: python:3.12-slim
    commands:
      - pip install --cache-dir .pip-cache -r requirements.txt
      - pip install pytest pytest-cov

  - name: lint
    image: python:3.12-slim
    commands:
      - pip install --cache-dir .pip-cache ruff
      - ruff check .

  - name: test
    image: python:3.12-slim
    commands:
      - pip install --cache-dir .pip-cache -r requirements.txt
      - pytest --cov=app --cov-report=term-missing tests/
    environment:
      DATABASE_URL: postgres://postgres:postgres@database:5432/testdb

  - name: deploy
    image: appleboy/drone-ssh
    settings:
      host:
        from_secret: deploy_host
      username:
        from_secret: deploy_user
      key:
        from_secret: deploy_key
      script:
        - cd /opt/myapp
        - git pull origin main
        - docker compose up -d --build
    when:
      branch:
        - main
      event:
        - push

services:
  - name: database
    image: postgres:16
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: testdb

Блок services запускает сопутствующие контейнеры (базы данных, Redis, и т.д.), доступные по имени сервиса как hostname. Условие when ограничивает шаг деплоя только для push в ветку main.

Пайплайн для Docker-образа

Сборка и публикация Docker-образа в private registry:

kind: pipeline
type: docker
name: build-image

steps:
  - name: build-and-push
    image: plugins/docker
    settings:
      repo: registry.example.com/myapp
      registry: registry.example.com
      username:
        from_secret: registry_user
      password:
        from_secret: registry_password
      tags:
        - latest
        - ${DRONE_COMMIT_SHA:0:8}
      cache_from:
        - registry.example.com/myapp:latest
    when:
      branch:
        - main
        - develop

trigger:
  event:
    - push
    - tag

Плагин plugins/docker выполняет docker build и docker push внутри контейнера. Тег формируется из первых 8 символов хеша коммита, что позволяет однозначно идентифицировать версию образа.

Управление секретами

Drone хранит секреты (пароли, SSH-ключи, токены) в зашифрованном виде и передаёт их в контейнеры только при выполнении пайплайна. Секреты не логируются и недоступны для pull request из форков.

Добавление секретов через CLI

Установите Drone CLI и настройте подключение:

# Установка CLI
curl -L https://github.com/harness/drone-cli/releases/latest/download/drone_linux_amd64.tar.gz | tar zx
sudo install -t /usr/local/bin drone

# Настройка подключения
export DRONE_SERVER=https://drone.example.com
export DRONE_TOKEN=ваш-персональный-токен  # из веб-интерфейса

# Добавление секретов для репозитория
drone secret add --repository org/myapp --name deploy_host --data 192.168.1.100
drone secret add --repository org/myapp --name deploy_user --data deployer
drone secret add --repository org/myapp --name deploy_key --data @/home/deployer/.ssh/id_ed25519

# Просмотр секретов (значения скрыты)
drone secret ls --repository org/myapp

Для организационных секретов (доступных всем репозиториям) используйте drone orgsecret add.

Условия запуска и матричные сборки

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

Условный запуск шагов

Шаги можно запускать по условиям — ветка, событие, статус предыдущих шагов:

steps:
  - name: notify-slack
    image: plugins/slack
    settings:
      webhook:
        from_secret: slack_webhook
      channel: deployments
      template: |
        {{#success build.status}}
          Сборка {{repo.name}}#{{build.number}} успешна
        {{else}}
          ОШИБКА: {{repo.name}}#{{build.number}} - {{build.link}}
        {{/success}}
    when:
      status:
        - success
        - failure
      branch:
        - main

Матричные сборки

Для тестирования на нескольких версиях Python или Node.js используйте несколько пайплайнов:

kind: pipeline
type: docker
name: python-3.11

steps:
  - name: test
    image: python:3.11
    commands:
      - pip install -r requirements.txt
      - pytest

---
kind: pipeline
type: docker
name: python-3.12

steps:
  - name: test
    image: python:3.12
    commands:
      - pip install -r requirements.txt
      - pytest

Разделитель --- определяет отдельные пайплайны, которые запускаются параллельно. Это удобнее матриц Jenkins — каждый пайплайн полностью автономен.

Кэширование и оптимизация скорости

Без кэширования каждая сборка скачивает зависимости заново, что значительно замедляет CI. Drone решает эту проблему через volume-плагины и общие кэши.

Кэш зависимостей через volume

Для кэширования между сборками используйте host volume или плагин кэширования:

kind: pipeline
type: docker
name: default

steps:
  - name: restore-cache
    image: plugins/s3-cache
    settings:
      endpoint: http://minio:9000
      access_key:
        from_secret: minio_access
      secret_key:
        from_secret: minio_secret
      restore: true
      mount:
        - .pip-cache
        - node_modules

  - name: install
    image: python:3.12
    commands:
      - pip install --cache-dir .pip-cache -r requirements.txt

  - name: rebuild-cache
    image: plugins/s3-cache
    settings:
      endpoint: http://minio:9000
      access_key:
        from_secret: minio_access
      secret_key:
        from_secret: minio_secret
      rebuild: true
      mount:
        - .pip-cache
        - node_modules

Альтернатива — примонтировать host-директорию через volumes в конфигурации Runner, но это менее безопасно и не работает при нескольких Runner-ах.

Масштабирование и отказоустойчивость

При росте команды один Runner может не справляться с нагрузкой. Drone легко масштабируется горизонтально — достаточно добавить дополнительные Runner-ы на других серверах.

Добавление Runner-ов

Разверните Docker Runner на дополнительном сервере, указав адрес Drone Server:

docker run -d \
  --name drone-runner \
  --restart always \
  -e DRONE_RPC_PROTO=https \
  -e DRONE_RPC_HOST=drone.example.com \
  -e DRONE_RPC_SECRET=9c4f2e8a1b3d5f7e0a2c4b6d8e0f1a3c \
  -e DRONE_RUNNER_CAPACITY=4 \
  -e DRONE_RUNNER_NAME=runner-02 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  drone/drone-runner-docker:1

Runner автоматически регистрируется на сервере и начинает принимать задания. Для production рекомендуется переключить базу данных Drone Server с SQLite на PostgreSQL:

DRONE_DATABASE_DRIVER: postgres
DRONE_DATABASE_DATASOURCE: postgres://drone:password@postgres:5432/drone?sslmode=disable

Часто задаваемые вопросы

Да, Drone нативно поддерживает GitHub. Замените переменные окружения: DRONE_GITHUB_CLIENT_ID, DRONE_GITHUB_CLIENT_SECRET вместо Gitea-переменных. Создайте OAuth App в GitHub Settings → Developer settings → OAuth Apps с callback URL https://drone.example.com/login.

Используйте переменную DRONE_USER_FILTER=org1,org2 для ограничения по организациям GitHub/Gitea. Для более тонкого контроля задайте DRONE_REGISTRATION_CLOSED=true и добавляйте пользователей вручную через CLI: drone user add username. Администраторов назначайте через drone user update username --admin.

Сервер Drone потребляет около 50 МБ RAM и минимум CPU. Основные ресурсы уходят на Runner — каждый запущенный пайплайн это отдельный Docker-контейнер. Для Runner с capacity=4 рекомендуется минимум 4 ядра CPU и 8 ГБ RAM. На VPS с 2 ГБ RAM можно запустить Runner с capacity=1-2.

Миграция проходит поэтапно: начните с новых проектов на Drone, а существующие Jenkinsfile конвертируйте постепенно. Общая логика пайплайнов сохраняется — замените stage на step, agent docker на image, withCredentials на from_secret. Плагины Jenkins заменяются Docker-образами из Drone Plugin Registry.

Нужна помощь с настройкой?

Специалисты АйТи Фреш помогут с внедрением и настройкой — 15+ лет опыта, обслуживание от 15 000 ₽/мес

📞 Связаться с нами
#Drone CI#CI/CD#Docker pipeline#непрерывная интеграция#автоматизация деплоя#Gitea CI#DevOps инструменты#Drone настройка
Комментарии 0

Оставить комментарий

загрузка...