Drone CI в Docker: лёгкий self-hosted пайплайн для небольшой команды
Привет! Я Евгений Семёнов, директор АйТи Фреш. Знаете, к нам часто приходят клиенты с командами из 5–10 разработчиков, которым до зарезу нужен собственный CI/CD. Но вот незадача: возиться с Jenkins и его бесконечными плагинами они категорически не хотят. В таких случаях мой однозначный выбор — Drone. У нас в АйТи Фреш этот инструмент уже прекрасно себя показал у десятка наших клиентов, обычно в связке с Gitea. Только представьте: один сервер, один раннер, плюс простой YAML-файл в репозитории — и ваша система готова к бою! Звучит элементарно, правда? Дальше я расскажу вам, как мы его настраиваем с нуля на Ubuntu, чтобы он без проблем подружился с вашим Git-хостингом.
Почему Drone
Drone — это Go-шный бинарник, собранный как два контейнера: сервер и раннер. Сервер принимает вебхуки от Git-а, раннер исполняет шаги пайплайна в Docker. Никаких агентов на Java, никаких Groovy-скриптов. Всё описывается в файле .drone.yml в корне репозитория.
- Аппетиты у Drone весьма скромные: сам сервер потребляет около 100 МБ ОЗУ, а раннер — всего 150 МБ. Вполне экономно, правда?
- Установка Drone? На любом Docker-хосте он поднимется буквально за 10 минут. Это невероятно быстро!
- Что касается обновлений — никаких сложностей! Просто меняем теги Docker-образов. Проще не бывает!
- Веб-интерфейс чистый, без легаси.
Конечно, не бывает идеальных решений. У Drone есть свои нюансы: комьюнити тут поменьше, чем у таких гигантов, как GitLab CI или GitHub Actions. Некоторые плагины, увы, уже устарели. А за корпоративные фишки вроде SSO или аудита придётся доплатить — они доступны только в платной Harness-версии.
Что понадобится
- Нам нужен сервер с установленными Docker и docker compose. Неважно, используете ли вы Ubuntu 22.04, 24.04 или Debian 12 — работать будет одинаково стабильно.
- Домен, например
ci.company.ru, с wildcard DNS или отдельной A-записью. - Для вашего Git-хостинга — будь то Gitea, GitHub или GitLab — понадобится зарегистрировать OAuth-приложение. Это стандартный шаг.
- Не забудьте про сертификат: подойдёт как бесплатный Let's Encrypt, так и ваш собственный внутренний PKI. Кстати, мы в ITFresh часто предпочитаем корпоративный AD CS.
Регистрация OAuth в Gitea
Для примера возьмём Gitea. Вам нужно зайти в Site Administration, затем в Applications и там создать новое 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.
Кэширование зависимостей
Каждый раз при запуске качать все пакеты заново? Это же так долго и неэффективно! Как мы решаем эту проблему?
- Чтобы не тратить время на повторное скачивание зависимостей, мы используем Volume-кэш. Мы просто монтируем директории, скажем, pip, npm или go, в специальный volume, который, что крайне важно, сохраняет своё содержимое между всеми запусками.
- S3-кэш через плагин
drone-s3-cache. - Ещё один лайфхак для ускорения — это Prebuilt-образ с зависимостями. Мы регулярно пересобираем такой «базовый» образ, куда уже включены все нужные библиотеки, и используем его на первых шагах сборки. Это здорово экономит время!
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 года к нам обратились ребята из веб-студии. Семь разработчиков, 14 активных проектов на Laravel и Vue. Представьте, до нас они деплоили всё вручную, через SSH! Задача была чёткой: поднять полноценный CI/CD для автотестов и автоматического деплоя на стейджинг и прод. Gitea у них уже была, а вот идея связываться с Jenkins их, честно говоря, сильно пугала.
За 2 рабочих дня мы развернули Drone на виртуалке 4 vCPU / 8 ГБ ОЗУ (наш сервер Dell Xeon Platinum 8280, дата-центр МТС Москва), настроили общий .drone.yml-шаблон и подключили 14 репозиториев. Стоимость работ — 34 000 руб. Через месяц время деплоя на стейджинг сократилось с 20 минут ручных действий до 90 секунд автоматом.
Типичные грабли
- Неправильный RPC_SECRET. Раннер не подключается к серверу. Проверяйте, что один и тот же в обеих переменных.
- OAuth redirect mismatch. В настройках Gitea ровно тот же URL, что в DRONE_SERVER_HOST (с протоколом).
- Нет места на /var/lib/docker. Образы для сборок копятся. Настройте
docker system pruneпо cron в раннере. - Медленные сборки. Включите кэш зависимостей, используйте слим-образы, параллельные шаги.
- Отвалы в середине пайплайна. Чаще всего сеть в docker-in-docker. Добавляйте retries, увеличивайте таймауты в плагинах.
Настроим 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 — оптимум.
