MAATRIX / Блог / Drone CI на Ubuntu 24.04: пошаговая установка

Drone CI на Ubuntu 24.04: пошаговая установка

MAATRIX

Jenkins тянет за собой Java, плагины и вечную возню с агентами, а GitHub Actions привязывает вас к чужой инфраструктуре и лимитам минут. Drone CI устроен иначе: сам сервер — один Go-бинарник в Docker-контейнере, а каждый шаг пайплайна выполняется в отдельном изолированном контейнере без общего состояния. Ниже — установка Drone с нуля на чистом VPS с Ubuntu 24.04: сервер, runner, интеграция с Git-провайдером и первый рабочий .drone.yml.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Как устроен Drone и почему шаги — это контейнеры

Drone состоит из двух компонентов, которые физически могут жить на разных машинах:

  • Server — веб-интерфейс, хранилище настроек и очередь заданий (сборок). Он ничего не собирает сам.
  • Runner — демон, который забирает задания из очереди и выполняет их. Для Docker-runner каждый шаг пайплайна из .drone.yml — это отдельный docker run с указанным образом. Шаг test может работать в golang:1.23, шаг build — в docker:24, и они не делят процессы между собой, только рабочую директорию через volume.

Из этого вытекает практическая особенность: если вам нужен кеш зависимостей (npm, pip, go mod) между сборками — его придётся организовывать явно, через volume или внешний кеш-плагин, а не через "постоянный агент", как в Jenkins. Это делает пайплайны воспроизводимыми (одна и та же сборка всегда стартует с чистого состояния), но требует немного другого мышления при переносе существующих CI-скриптов.

Drone поддерживает GitHub, GitLab, Gitea, Bitbucket и Gogs как источники репозиториев — авторизация идёт через OAuth-приложение, которое вы регистрируете у провайдера.

Требования к серверу и подготовка

Для сервера Drone с несколькими репозиториями и умеренной нагрузкой достаточно:

РесурсМинимумКомфортно
CPU1 vCPU2 vCPU
RAM1 ГБ2-4 ГБ
Диск20 ГБ SSD40+ ГБ (образы копятся)
ОСUbuntu 24.04 LTS

Runner можно держать на том же сервере, что и Server — для старта этого достаточно. При росте числа параллельных сборок runner логично вынести на отдельный VPS, чтобы сборки не съедали ресурсы у веб-интерфейса.

Подключитесь по SSH (лучше сразу по ключу, а не по паролю) и обновите систему:

sudo apt update && sudo apt upgrade -y
sudo hostnamectl set-hostname drone-ci

Понадобится домен или поддомен (например, ci.example.com), указывающий A-записью на IP сервера — Drone требует HTTPS для OAuth-коллбэков от GitHub/GitLab, и без валидного домена интеграция с провайдером просто не заработает.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Установка Docker

Drone Server и Docker-runner разворачиваются как контейнеры, поэтому Docker обязателен. Если на сервере ещё нет Docker, ставим его официальным способом:

sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Проверка:

sudo docker run hello-world

Регистрация OAuth-приложения у Git-провайдера

Drone не хранит собственные пароли пользователей — вход идёт через OAuth провайдера репозиториев. Разберём на примере GitHub, для GitLab и Gitea шаги аналогичны с поправкой на терминологию.

  1. Зайдите в GitHub → Settings → Developer settings → OAuth Apps → New OAuth App.
  2. Заполните поля:
  • Homepage URL: https://ci.example.com
  • Authorization callback URL: https://ci.example.com/login
  1. Сохраните и скопируйте Client ID и Client Secret — они понадобятся в переменных окружения сервера.

Для Gitea (если вы держите собственный Git-сервер) приложение регистрируется в Settings → Applications, callback URL тот же формат: https://ci.example.com/login.

Также сгенерируйте случайный RPC_SECRET — общий секрет между Server и Runner:

openssl rand -hex 16

Сохраните значение, оно понадобится в обоих docker-compose.yml.

Установка и запуск Drone Server

Создадим директорию проекта и файл docker-compose.yml:

mkdir -p ~/drone && cd ~/drone
# ~/drone/docker-compose.yml
services:
  drone-server:
    image: drone/drone:2
    container_name: drone-server
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:80"
    volumes:
      - drone-data:/data
    environment:
      - DRONE_GITHUB_CLIENT_ID=ваш_client_id
      - DRONE_GITHUB_CLIENT_SECRET=ваш_client_secret
      - DRONE_RPC_SECRET=ваш_rpc_secret
      - DRONE_SERVER_HOST=ci.example.com
      - DRONE_SERVER_PROTO=https
      - DRONE_USER_CREATE=username:ваш-github-логин,admin:true

volumes:
  drone-data:

Ключевые переменные:

  • DRONE_SERVER_HOST / DRONE_SERVER_PROTO — публичный адрес, по которому Drone доступен извне (нужен для формирования правильных ссылок и webhook-URL).
  • DRONE_USER_CREATE — сразу создаёт вашего пользователя администратором при первом старте, без этого первый вход придётся настраивать отдельно.
  • Порт сервиса намеренно привязан к 127.0.0.1:8080 — наружу Drone будет смотреть только через reverse proxy с HTTPS, напрямую порт 80/8080 наружу не открываем.

Запуск:

sudo docker compose up -d
sudo docker compose logs -f drone-server

В логах должно появиться сообщение о старте HTTP-сервера на порту 80 внутри контейнера.

HTTPS через reverse proxy

GitHub требует HTTPS для OAuth callback, поэтому перед Drone нужен обратный прокси с автоматическим TLS. Caddy для этого удобнее nginx+certbot — сертификат выпускается и продлевается сам, без крон-задач; подробная установка отдельно разобрана в статье про Caddy с авто-SSL на Ubuntu 24.04, здесь — минимальный конфиг под Drone.

Ставим Caddy и прописываем Caddyfile:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install -y caddy
# /etc/caddy/Caddyfile
ci.example.com {
    reverse_proxy 127.0.0.1:8080
}
sudo systemctl reload caddy

Caddy сам получит сертификат Let's Encrypt при первом обращении к домену по HTTPS. Не забудьте открыть порты в фаерволе — если вы ещё не настраивали UFW, инструкция есть в статье про firewall UFW на Ubuntu 24.04:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Теперь https://ci.example.com должен открывать страницу входа Drone. Войдите через GitHub — если callback URL совпадает с тем, что указан в OAuth-приложении, авторизация пройдёт без ошибок.

Установка Runner и подключение репозитория

Runner можно поднять тем же docker compose, добавив сервис в тот же файл или в отдельный на другом сервере:

# добавить в docker-compose.yml
  drone-runner:
    image: drone/drone-runner-docker:1
    container_name: drone-runner
    restart: unless-stopped
    depends_on:
      - drone-server
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DRONE_RPC_PROTO=http
      - DRONE_RPC_HOST=drone-server
      - DRONE_RPC_SECRET=ваш_rpc_secret
      - DRONE_RUNNER_CAPACITY=2
      - DRONE_RUNNER_NAME=runner-1

DRONE_RPC_HOST=drone-server работает благодаря общей Docker-сети, которую compose создаёт автоматически между сервисами одного файла. DRONE_RUNNER_CAPACITY — сколько сборок runner выполняет одновременно параллельно; для 2 vCPU разумный старт — 2.

Runner монтирует /var/run/docker.sock — это даёт ему возможность запускать контейнеры для шагов пайплайна "рядом" с собой (Docker-in-Docker через сокет хоста, а не вложенный демон). Учтите: это даёт runner-контейнеру фактический root-доступ к хосту через Docker API, поэтому runner должен работать на сервере, где нет ничего чувствительного, либо изолированном соответствующим образом.

Перезапускаем стек:

sudo docker compose up -d

В веб-интерфейсе Drone (раздел Repositories) активируйте нужный репозиторий — Drone сам создаст webhook в GitHub на push и pull_request события.

Первый .drone.yml и запуск пайплайна

В корне репозитория создайте файл .drone.yml:

kind: pipeline
type: docker
name: default

steps:
  - name: test
    image: node:20
    commands:
      - npm ci
      - npm test

  - name: build
    image: docker:24
    volumes:
      - name: dockersock
        path: /var/run/docker.sock
    commands:
      - docker build -t myapp:latest .

volumes:
  - name: dockersock
    host:
      path: /var/run/docker.sock

trigger:
  branch:
    - main

Каждый steps — отдельный контейнер, image задаёт окружение шага. Шаг build тоже получает доступ к сокету хоста, чтобы собирать Docker-образы изнутри пайплайна (тот же принцип DinD через сокет, что и у самого runner). После коммита с этим файлом в ветку main сборка должна появиться на вкладке Activity сервера в течение нескольких секунд после push — webhook срабатывает почти мгновенно.

Если сборка не стартует, первым делом смотрите логи runner:

sudo docker compose logs -f drone-runner

Частая причина тишины — секрет DRONE_RPC_SECRET не совпадает между server и runner, тогда runner не может забрать задание из очереди, хотя формально числится подключённым.

Резервное копирование и хранение секретов пайплайна

Вся конфигурация и история сборок Drone хранятся в SQLite-базе внутри volume drone-data — если сервер потеряется, потеряется и настройка. Бэкап делается просто копированием volume:

sudo docker run --rm \
  -v drone_drone-data:/data \
  -v ~/drone-backup:/backup \
  alpine tar czf /backup/drone-data-$(date +%F).tar.gz -C /data .

Для более системного подхода к бэкапам Docker-volume — с ротацией и расписанием — пригодится статья как настроить бэкап Docker volume на VPS.

Секреты для пайплайнов (токены реестров, API-ключи деплоя) не кладите в .drone.yml открытым текстом — используйте раздел Settings → Secrets в веб-интерфейсе репозитория, они хранятся зашифрованными в базе Drone и подставляются в шаги через environment: from_secret.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Чем Drone принципиально отличается от Jenkins?

Drone не требует установки плагинов и настройки агентов — вся логика пайплайна декларативно описана в .drone.yml, а каждый шаг выполняется в чистом одноразовом контейнере. Это проще поддерживать, но требует явного описания кеширования между шагами, которое в Jenkins часто получается "бесплатно" за счёт постоянного агента.

Можно ли обойтись без reverse proxy и HTTPS?

Технически Drone запустится и по HTTP, но OAuth-провайдеры (GitHub, GitLab) требуют HTTPS для callback URL в продакшене, так что без сертификата авторизация не пройдёт. Единственное исключение — локальный тестовый стенд без реальной OAuth-интеграции.

Runner обязательно держать на том же сервере, что и Server?

Нет, это два независимых компонента, которые общаются по сети через DRONE_RPC_HOST. Для нагруженных проектов логично вынести runner (или несколько runner-ов) на отдельные серверы, масштабируя мощность сборки отдельно от веб-интерфейса.

Что если нужно собирать под ARM или несколько архитектур?

Drone runner сам выполняется на архитектуре хоста — для сборки под ARM понадобится runner на ARM-сервере либо использование docker buildx внутри шага с QEMU-эмуляцией, что заметно медленнее нативной сборки.

Как обновить Drone до новой версии?

Замените тег образа в docker-compose.yml (например, drone/drone:2 на конкретный минорный релиз) и выполните docker compose pull && docker compose up -d — база в volume сохраняется между обновлениями, но перед мажорным апгрейдом стоит сделать бэкап volume.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →