· 16 мин чтения

Drone CI в Docker: лёгкий self-hosted пайплайн для небольшой команды

Drone CI в Docker: лёгкий self-hosted пайплайн для небольшой команды

Я Семёнов Евгений Сергеевич, директор АйТи Фреш. Когда клиент из 5–10 разработчиков просит свой CI/CD, и при этом не хочет тащить Jenkins с его джунглями плагинов — я ставлю Drone. У нас на практике он крутится у десятка заказчиков рядом с Gitea. Один сервер, один раннер, YAML в репозитории — и всё. Расскажу, как поднять с нуля на Ubuntu и связать с Git-хостингом.

Почему Drone

Drone — это Go-шный бинарник, собранный как два контейнера: сервер и раннер. Сервер принимает вебхуки от Git-а, раннер исполняет шаги пайплайна в Docker. Никаких агентов на Java, никаких Groovy-скриптов. Всё описывается в файле .drone.yml в корне репозитория.

Минусы: комьюнити меньше чем у GitLab CI или GitHub Actions, часть плагинов устарели, корпоративные фичи (SSO, аудит) — в платной Harness-версии.

Что понадобится

Регистрация OAuth в Gitea

Для примера берём Gitea. Идём в Site Administration → Applications → Create OAuth2 Application.

Application Name: Drone
Redirect URI: https://ci.company.ru/login

# Сохраняем Client ID и Client Secret

Docker Compose для Drone

Файл /opt/drone/docker-compose.yml:

services:
  drone-server:
    image: drone/drone:2.24
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - drone-data:/data
    environment:
      DRONE_GITEA_SERVER: https://git.company.ru
      DRONE_GITEA_CLIENT_ID: ${GITEA_CLIENT_ID}
      DRONE_GITEA_CLIENT_SECRET: ${GITEA_CLIENT_SECRET}
      DRONE_RPC_SECRET: ${RPC_SECRET}
      DRONE_SERVER_HOST: ci.company.ru
      DRONE_SERVER_PROTO: https
      DRONE_USER_CREATE: username:admin,admin:true
      DRONE_LOGS_TEXT: "true"

  drone-runner:
    image: drone/drone-runner-docker:1.8
    restart: unless-stopped
    depends_on: [drone-server]
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      DRONE_RPC_HOST: drone-server
      DRONE_RPC_PROTO: http
      DRONE_RPC_SECRET: ${RPC_SECRET}
      DRONE_RUNNER_CAPACITY: 4
      DRONE_RUNNER_NAME: runner-1

volumes:
  drone-data:

В .env:

GITEA_CLIENT_ID=xxxxx
GITEA_CLIENT_SECRET=yyyyy
RPC_SECRET=$(openssl rand -hex 16)
docker compose up -d
docker compose logs -f drone-server

Перед Drone-сервером ставлю nginx/traefik с Let's Encrypt, порт 8080 внутрь, 443 наружу. Для Traefik — пару меток на сервис, готово.

Пример .drone.yml для Python-приложения

kind: pipeline
type: docker
name: default

steps:
  - name: tests
    image: python:3.12-slim
    commands:
      - pip install -r requirements.txt
      - pytest --cov=app tests/

  - name: build-image
    image: plugins/docker
    settings:
      registry: registry.company.ru
      repo: registry.company.ru/myapp
      tags:
        - ${DRONE_COMMIT_SHA:0:8}
        - latest
      username:
        from_secret: registry_user
      password:
        from_secret: registry_pass
    when:
      branch: [main]

  - name: deploy
    image: appleboy/drone-ssh
    settings:
      host: prod.company.ru
      username: deploy
      key:
        from_secret: ssh_key
      script:
        - cd /opt/myapp
        - docker compose pull
        - docker compose up -d
    when:
      branch: [main]

Секреты и переменные

ГдеЧтоКогда применять
Репозиторий → Settings → SecretsИндивидуальные секретыКреды реестра, SSH-ключи, API-токены
Organization secretsОбщие для всех репо организацииОбщий Sentry DSN, Slack webhook
Переменные окружения в YAMLНесекретные значенияИмя окружения, версии

Я всегда ставлю у секретов флаг «Allow Pull Requests» выключенным, иначе форк-PR может слить секреты через echo $SECRET.

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

На каждом запуске качать пакеты заново — долго. Решения:

steps:
  - name: restore-cache
    image: meltwater/drone-cache
    settings:
      backend: filesystem
      mount:
        - .venv
        - node_modules
      restore: true

  - name: build
    image: python:3.12
    commands:
      - pip install --target .venv -r requirements.txt

Реальный кейс: Drone для студии веб-разработки

В июне 2025 года к нам пришли ребята из веб-студии — 7 разработчиков, 14 активных проектов на Laravel + Vue. До нас — всё деплоили вручную по SSH. Задача: поднять CI/CD для автотестов и авто-деплоя на стейджинг и прод. Gitea у них уже была, Jenkins пугал.

За 2 рабочих дня мы развернули Drone на виртуалке 4 vCPU / 8 ГБ ОЗУ (наш сервер Dell Xeon Platinum 8280, дата-центр МТС Москва), настроили общий .drone.yml-шаблон и подключили 14 репозиториев. Стоимость работ — 34 000 руб. Через месяц время деплоя на стейджинг сократилось с 20 минут ручных действий до 90 секунд автоматом.

Типичные грабли

Настроим CI/CD под ваш стек

Мы ставим Drone, GitLab CI, Gitea Actions, Jenkins — в зависимости от того, что действительно подходит вашей команде. 15+ лет админского опыта, 8 серверов Dell Xeon Platinum 8280 с 40G Mellanox в дата-центре МТС Москва для отказоустойчивого хостинга ваших CI.

Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш

FAQ — Drone CI

Чем Drone лучше Jenkins?
Drone легче в настройке, пайплайны описаны в YAML и хранятся в репозитории. Сервер — один контейнер, раннеры — отдельные. Занимает 200 МБ ОЗУ против 1,5 ГБ у Jenkins. Но экосистема плагинов у Jenkins шире.
С чем интегрируется Drone?
Gitea, GitHub, GitLab, Bitbucket, Gogs. Использует OAuth для авторизации. Webhooks настраиваются автоматически при активации репозитория в веб-интерфейсе Drone.
Сколько раннеров нужно?
Для одной команды из 5–10 разработчиков — один docker-runner на сервере. Для параллельных сборок можно ставить несколько с увеличенным DRONE_RUNNER_CAPACITY. На нашей инфраструктуре — по 2 раннера на клиентский проект.
Как хранить секреты в Drone?
Через веб-интерфейс репозитория, вкладка Secrets. Секреты прокидываются как переменные окружения только в шаги, которые их явно запрашивают. Для репозиториев с публичным pull request — обязательно ставьте pull_request_read_only=true.
Можно ли развернуть Drone без Docker?
Сервер — да, это один бинарь Go. Но раннер с docker-пайплайнами всё равно требует доступа к Docker-демону. Есть alternative раннеры: exec, ssh, kubernetes, digitalocean. Для большинства задач docker-runner — оптимум.

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.