Установка и настройка Drone в Ubuntu 16.04

Drone – это популярная система непрерывной интеграции, основанная на Go. Она может взаимодействовать с GitHub, GitLab и Bitbucket, отслеживать изменения в коде и тестировать новые функции.

Данное руководство поможет установить и настроить среду непрерывной интеграции Drone в инфраструктуре. В качестве фронтенда Drone будет использоваться Nginx, защищенный сертификатом Let’s Encrypt. Сертификат зашифрует запросы к веб-интерфейсу Drone и позволит серверу непрерывной интеграции (дальше – НИ) безопасно взаимодействовать с сервером исходного кода.

Требования

Также вам может пригодиться руководство Установка и использование Docker в Ubuntu 16.04.

В результате на сервере Drone будет:

  • Пользователь sudo.
  • Брандмауэр UFW. Он будет блокировать все соединения, кроме SSH, HTTP и HTTPS по портам 22, 80 и 443 соответственно.
  • Docker и Docker Compose.
  • Сервер Nginx, защищенный SSL-сертификатом от Let’s Encrypt.

Добавление Drone в репозиторий исходного кода

Чтобы отслеживать изменения и выполнять тесты, Drone нужен доступ к репозиторию исходного кода проекта. Drone можно интегрировать с GitHubGitLabGogsBitbucket Cloud и Bitbucket Server.

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

Примечание: Если вы используете другой репозиторий исходного кода, следуйте приведенным выше ссылкам, чтобы получить инструкции по настройке вашего программного обеспечения.

Откройте аккаунт GitHub. Нажмите на иконку пользователя в верхнем правом углу и выберите Settings.

Найдите элемент OAuth applications в разделе Developer settings в левой части экрана.

На следующей странице нажмите Register a new application.

Затем вы увидите регистрационную форму приложения OAuth.

Примечание: Эти поля есть в GitHub. Формы других провайдеров могут отличаться.

Нужно будет заполнить следующие поля:

  • Application name: Введите имя интегрируемого приложения. Если у вас нет особых потребностей, можно просто ввести Drone.
  • Homepage URL: Доменное имя сервера Drone. Поскольку трафик шифруется, используйте https:// в начале имени.
  • Application description: Простое описание приложения и целей Drone.
  • Authorization callback URL: Нужно указать https://, затем домен сервера Drone и секцию /authorize. К примеру, для домена example.com это поле выглядит так: https://example.com/authorize.

Чтобы зарегистрировать приложение, нажмите Register application.

На следующей странице вы увидите подробные данные о приложении. Скопируйте здесь Client ID и Client Secret: эти значения нужны для подключения Drone к аккаунту GitHub.

Загрузка образа Drone и подготовка к настройке

Теперь нужно установить Drone на сервер.

Drone распространяется в виде контейнера Docker. Контейнер будет автоматически загружен, если использовать его в файле Docker Compose. Чтобы загрузить образ, введите:

docker pull drone/drone:0.7

Образ Drone – это унифицированный контейнер, который можно запустить несколькими способами. В руководстве показано, как запустить один контейнер как сервер Drone, который координирует доступ к репозиторию, размещает веб-интерфейс и обслуживает API. Второй контейнер будет запущен в качестве агента Drone, который отвечает за создание и тестирование программного обеспечения из репозиториев.

Оба контейнера будут работать на хосте Drone с помощью Docker Compose. Создайте каталог конфигураций:

sudo mkdir /etc/drone

Создание файла Docker Compose для Drone

Создайте файл Docker Compose:

sudo nano /etc/drone/docker-compose.yml

Укажите версию файла (в данном случае – 3). После этого можно определить сервисы контейнеров.

Сервис drone-server запустит главный контейнер сервера Drone, прослушивающий порт 8000. Смонтируйте каталог /var/lib/drone в контейнере, чтобы система Drone могла хранить в нем свои данные. Также нужно настроить сервис для автоматического перезапуска и чтения переменных среды, определенных в файле /etc/drone/server.env (он будет создан позже).

Сервис drone-agent использует тот же образ, но запускается с помощью команды agent. Он получает инструкции от главного сервера Drone. Пока ему не нужен доступ к сети, его необходимо запустить после сервиса Drone. Также drone-agent необходим доступ к файлу сокета Docker, чтобы развернуть контейнеры и выполнить сборку и тестирование. Как и drone-server, этот сервис также автоматически перезагрузится и прочитает переменные среды в /etc/drone/agent.env.

Для настройки этих сервисов можно использовать следующий файл Docker Compose.

Примечание: В файлах YAML нужно внимательно проставлять отступы.

version: '3'
services:
drone-server:
image: drone/drone:0.7
ports:
- 127.0.0.1:8000:8000
volumes:
- /var/lib/drone:/var/lib/drone
restart: always
env_file:
- /etc/drone/server.env
drone-agent:
image: drone/drone:0.7
command: agent
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: always
env_file:
- /etc/drone/agent.env

Файл переменных среды сервера Drone

Теперь нужно создать файл для хранения переменных среды, на который вы ссылались в файле Docker Compose.

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

LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 | head -c 65 && echo

Эта команда временно ограничивает диапазон символов в оболочке. Затем она берет поток случайных байтов из /dev/urandom и дополнительно отфильтровывает все неалфавитные символы. Первые 65 символов используются в качестве ключа.

Внимание: не копируйте приведенное ниже значение! Создайте свой собственный ключ!

ERmA7xubDvTa8i0wYBlljc9yjT1NJPG7xOlZBwAdMAmBYL4RZE4QngxWcCLowk9KN

Скопируйте ключ и используйте его в файле среды сервера.

Создайте новый файл /etc/drone/server.env и откройте его в текстовом редакторе:

sudo nano /etc/drone/server.env

Внутри нужно определить переменные среды, которые Drone использует для запуска сервиса, подключиться к провайдеру и указать политику авторизации. Здесь понадобятся скопированные ранее значения Client ID и Client Secret.

Для начала задайте значения DRONE_HOST и DRONE_SECRET. В DRONE_SECRET укажите ключ, который вы создали в командной строке. Параметр DRONE_HOST сообщает системе Drone общедоступный адрес. Это должен быть защищенный сертификатом Let’s Encrypt домен.

# Service settings
DRONE_SECRET=secret_generated_on_command_line
DRONE_HOST=https://example.com

Затем настройте интеграцию с провайдером, в данном случае это GitHub. Настройки могут отличаться в зависимости от потребностей проекта и настройки GitHub.

Заблокируйте установку Drone и отключите открытую регистрацию, установив в DRONE_OPEN значение false. Это означает, что войти смогут только учетные записи GitHub, которые указаны в DRONE_ADMIN.

Примечание: Если ваша команда разработчиков работает в качестве организации GitHub, лучше установить в DRONE_OPEN значение true и заменить DRONE_ADMIN на DRONE_ORGS. Параметр DRONE_ORGS позволяет указать одну или несколько организаций GitHub, чьи члены должны иметь доступ. Drone разблокирует регистрацию для пользователей, которые принадлежат к этим группам.

В DRONE_ADMIN нужно указать имя пользователя GitHub.

Затем активируйте плагин интеграции GitHub, установив в DRONE_GITHUB значение true. В строках DRONE_GITHUB_CLIENT и DRONE_GITHUB_SECRET укажите ключи, которые вы скопировали со страницы приложения GitHub OAuth во время регистрации приложения Drone.

# Service settings
DRONE_SECRET=secret_generated_on_command_line
DRONE_HOST=https://example.com
# Registration settings
DRONE_OPEN=false
DRONE_ADMIN=8hostblog
# GitHub Settings
DRONE_GITHUB=true
DRONE_GITHUB_CLIENT=Client_ID_from_GitHub
DRONE_GITHUB_SECRET=Client_Secret_from_GitHub

Настройка сервера завершена. Скопируйте значение DRONE_SECRET, а затем сохраните и закройте файл. Этот же ключ пригодится в настройке агента.

Файл переменных среды агента Drone

Создайте файл среды для агента Drone.

sudo nano /etc/drone/agent.env

В нем нужно определить только два значения. DRONE_SECRET должен соответствовать значению в файле server.env.

Параметр DRONE_SERVER будет определять способ подключения агента к серверному компоненту Drone. Значение начинается с префикса протокола wss:// (что значит, что соединение будет использовать зашифрованный веб-сокет), за которым следует доменное имя сервера Drone с секциями /ws/broker:

DRONE_SECRET=secret_generated_on_command_line
DRONE_SERVER=wss://example.com/ws/broker

Сохраните и закройте файл.

Unit-файл для Drone

После этого нужно определить файл unitd для управления службой Drone.

Откройте конфигурационный файл .service в каталоге /etc/systemd/system, чтобы настроить сервис:

sudo nano /etc/systemd/system/drone.service

Вставьте в файл:

[Unit]
Description=Drone server
After=docker.service nginx.service
[Service]
Restart=always
ExecStart=/usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml up
ExecStop=/usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml stop
[Install]
WantedBy=multi-user.target

Первый раздел указывает, что сервис нужно запускать после Docker и Nginx. Второй раздел настраивает перезапуск сервиса в случае сбоев и определяет команды для запуска и остановки сервиса Drone с помощью Docker Compose и файла переменных среды. Последний раздел добавляет сервис в автозагрузку.

Сохраните и закройте файл.

Прежде чем запустить сервис Drone, нужно настроить Nginx. Агент Drone должен иметь возможность подключаться к серверу Drone, для такого соединения необходим прокси-сервер Nginx.

Nginx как прокси-сервер Drone

Затем нужно изменить конфигурацию Nginx и настроить проксирование запросов на сервер Drone.

Откройте файл блока server, который обрабатывает защищенный сертификатом домен. Запросите атрибут server_name во всех включенных блоках server:

grep -R server_name /etc/nginx/sites-enabled
/etc/nginx/sites-enabled/default:   server_name example.com;
/etc/nginx/sites-enabled/default:   return 301 https://$server_name$request_uri;
/etc/nginx/sites-enabled/default:   server_name example.com;
/etc/nginx/sites-enabled/default:#  server_name example.com;

Согласно выводу домен (example.com) определяется в файле /etc/nginx/sites-enabled/default. Нужно отредактировать файл, связанный с этим доменным именем.

Возможно, в выводе будет что-то вроде:

/etc/nginx/sites-enabled/default:   server_name _;
/etc/nginx/sites-enabled/default:   return 301 https://$server_name$request_uri;
/etc/nginx/sites-enabled/default:   server_name _;
/etc/nginx/sites-enabled/default:#  server_name example.com;

В приведенном выше примере строки server_name _; представляют резервные блоки server. Спецификатор хоста «_» определяет недействительный хост.

В конфигурации они связаны с директивами listen, которые устанавливают параметр default_server, благодаря чему блок действует по умолчанию, когда запрашиваемый хост не соответствует ни одному блоку server. Если вы не можете найти определение server_name, которое соответствует вашему доменному имени, используйте файл, который определяет эти резервные блоки.

Откройте файл в редакторе:

sudo nano /etc/nginx/sites-enabled/default

Добавьте два раздела вне блока server.

upstream drone {
server 127.0.0.1:8000;
}
map $http_upgrade $connection_upgrade {
default upgrade;
''      close;
}
server {
. . .

Первый блок upstream настраивает drone, куда можно проксировать запросы. Директива server определяет способ подключения к сервису Drone по порту 8000.

Второй блок задает пользовательскую переменную $connection_upgrade на основе значения переменной $http_upgrade, которую Nginx устанавливает при получении HTTP-заголовка Upgrade. Если получен заголовок Upgrade, Nginx установит в переменной $connection_upgrade значение upgrade. Если заголовка нет, переменная получит значение close. Эти переменные позволяют устанавливать правильные заголовки при проксировании запросов WebSocket.

Затем найдите блок server с директивой listen 443. Замените содержимое блока location / следующим блоком. Обязательно закомментируйте или удалите любые другие опции в этом блоке, чтобы избежать конфликтов.

. . .
server {
listen 443 ssl;
. . .
location / {
# try_files $uri $uri/ =404;
proxy_pass http://drone;
include proxy_params;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_redirect off;
proxy_http_version 1.1;
proxy_buffering off;
chunked_transfer_encoding off;
proxy_read_timeout 86400;
}
. . .
}

Строка proxy_pass передает весь трафик, обслуживаемый этим блоком, в предыдущий, который вы определили ранее. Затем блок содержит определения заголовков прокси из файла proxy_params и дополнительные заголовки на основе параметров map.

Затем идут другие параметры прокси-сервера, что обеспечивает правильную работу прокси-сервера WebSocket и взаимодействие компонентов.

Тестирование настройки и перезапуск Nginx и Drone

Настройка завершена. Теперь нужно запустить или перезапустить сервисы.

Сначала проверьте настройки Nginx на наличие ошибок:

sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Если вывод сообщит об ошибках, вернитесь в файл и проверьте конфигурацию Nginx.

Когда ошибок не будет, перезапустите Nginx:

sudo systemctl restart nginx

Теперь, когда Nginx работает как прокси-сервер между агентом и сервером, можно запустить Drone:

sudo systemctl start drone

Убедитесь, что сервер успешно запущен:

sudo systemctl status drone
drone.service - Drone server
Loaded: loaded (/etc/systemd/system/drone.service; disabled; vendor preset: enabled)
Active: active (running) since Fri 2017-06-09 21:56:33 UTC; 2min 58s ago
Main PID: 15225 (docker-compose)
Tasks: 5
Memory: 37.7M
CPU: 1.544s
CGroup: /system.slice/drone.service
├─15225 /usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml up
└─15228 /usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml up
. . .
Jun 09 21:56:35 drone docker-compose[15225]: drone-agent_1   | pipeline: request next execution

Если в выводе есть строка active (running) и нет ошибок, значит, сервис Drone работает правильно.

В случае ошибки проверьте логи Nginx:

sudo less /var/log/nginx/error.log

Чтобы проверить логи Drone, введите:

sudo journalctl -u drone

Если ошибок нет, можно добавить Drone в автозагрузку:

sudo systemctl enable drone

Вход в Drone

Теперь нужно войти в интерфейс приложения Drone и авторизовать взаимодействие с аккаунтом GitHub.

Посетите доменное имя своего сервера в веб-браузере, чтобы открыть веб-интерфейс Drone:

https://example.com

При первом входе нужно ввести учетные данные.

Нажмите login, чтобы аутентифицироваться в Drone с помощью учетной записи GitHub и OAuth. Если вы еще не вошли в GitHub, вам будет необходимо сначала войти в аккаунт GitHub.

После этого вам будет предложено разрешить Drone получать доступ к учетной записи GitHub.

Просмотрите запрашиваемые разрешения и внесите любые поправки. А затем нажмите Authorize username.

Вы будете перенаправлены на сервер Drone.

Здесь можно настраивать и автоматически тестировать новый код в репозитории.

Чтобы настроить Drone для автоматического запуска тестов и определить файл .drone.yml, ознакомьтесь с документацией Drone.

Tags: , , , , ,