如何在Ubuntu 16.04上安装和配置Drone

Drone是Go中建立的流行的连续集成和交付平台。它集成了许多流行的版本控制资料库服务,如GitHub,GitLab和Bitbucket,以监视代码更改,并自动构建和测试更改,因为他们...

介绍

Drone是Go中建立的流行的连续集成和交付平台。 它与许多流行版本控制存储库服务(如GitHub,GitLab和Bitbucket)集成,用于监视代码更改,并在更改时自动构建和测试更改。

在本指南中,我们将演示如何为您的基础架构设置完整的Drone连续集成环境。 我们将安装Drone并将其配置为与源代码存储库集成。 一路上,我们将配置Nginx,受Let's Encrypt的保护,作为Drone的前端。 这将加密对Drone Web界面的请求,并允许CI服务器与源代码服务器安全地集成。

先决条件

为了开始,您应该有一个配置了非root用户的Ubuntu 16.04服务器用于管理任务。 服务器还应该有防火墙来过滤传入的连接。 您可以通过遵循Ubuntu 16.04初始服务器设置指南来了解如何配置这些项目。

您将必须完成一些额外的步骤来满足我们的设置的其他要求。 因为Drone主要作为Docker映像分发,我们将使用Docker Compose来管理CI服务器容器。 为了安全性和性能目的,我们将通过让我们加密保护的Nginx实例来代理对Drone的请求。 您将需要一个连接到您的CI服务器的域名才能正确设置。

在开始之前,请使用以下文章来设置以下附加要求:

完成上述指南后,您的Drone服务器应具有:

  • 为管理任务配置的sudo用户
  • 已启用UFW防火墙。 应该分别阻止端口22,80和443上的SSH,HTTP和HTTPS请求之外的所有连接。
  • Docker和Docker Compose已安装。
  • 配置了由Let's Encrypt提供的SSL证书的Nginx服务器

准备开始时继续下面。

将应用程序添加到您的源代码库

为了监控代码更改以触发构建和测试阶段,Drone将需要访问您的源代码存储库。 Drone可以与GitHubGitLabGogsBitbucket CloudBitbucket Server集成

在本指南中,我们将重点介绍与GitHub存储库的集成,但其他系统的过程应该相似。 如果您正在使用不同的源代码存储库,请按照上面的相应链接了解您需要的具体软件配置。

首先访问您的GitHub帐户。 点击右上角的用户图标,然后从下拉菜单中选择设置

DroneGitHub设置

接下来,在屏幕左侧的“ 开发人员设置”部分找到OAuth应用程序项目:

DroneOAuth应用程序

在下面的页面上,单击注册一个新的应用程序

Drone新应用程序

接下来,您将看到OAuth应用程序注册表单:

Drone注册一个新的应用程序

您将需要填写以下字段(这些字段存在于GitHub上,其他存储库提供程序可能会有不同的提示):

  • 应用程序名称 :您选择标识集成的名称。 如果没有特殊需要,“Drone”是一个不错的选择。
  • 主页网址 :您的Drone服务器的域名。 在这里使用https:// ,因为我们正在使用安全域。
  • 应用描述 :简单描述Drone及其目的。
  • 授权回调URL :这必须是https://模式说明符,后跟您的Drone服务器的域名,后跟/authorize 如果我们的域名是example.com ,这个文件将是https:// example.com /authorize

准备好后,单击注册应用程序

在下一页上,您将看到新应用程序的详细信息。 我们需要的两个项目是客户端ID客户端密码

Drone客户端信息

复制这两个值以供以后使用。 我们需要将Drone连接到我们的GitHub帐户。

拉取Drone Docker图像并准备配置

现在您已将Drone服务器注册到存储库提供程序,您可以在服务器上安装和配置Drone。

Drone作为Docker容器分发,因此如果我们在Docker Compose文件中使用它,它将被自动下载。 为了加快进程,我们可以提前拉下形象:

docker pull drone/drone:0.7

DroneDocker图像是一个统一的容器,可以通过几种不同的方式运行。 我们将运行一个作为Drone服务器运行的容器,该服务器协调存储库访问,托管Web UI,并提供API。 使用不同设置的相同图像,我们将运行另一个容器作为Drone代理,它负责从配置的存储库构建和测试软件。

我们将使用Docker Compose在Drone主机上运行这两个容器。 首先创建一个配置目录来存储我们需要的文件:

sudo mkdir /etc/drone

接下来,我们将在其中创建几个文件来配置我们的服务。

为Drone创建Docker Compose文件

首先,在配置目录中创建一个Docker Compose文件:

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

在里面,我们将标记Docker Compose文件格式为“3”版本。 之后,我们将为上述两种服务定义服务。

drone-server服务将启动监听端口8000上的主Drone服务器容器。我们将在容器内装载主机的/var/lib/drone目录,以使Drone可以保留其数据。 我们将配置服务以自动重新启动,并以我们将在/etc/drone/server.env创建的文件中定义的环境变量的形式阅读更详细的配置/etc/drone/server.env

drone-agent服务使用与agent命令一起启动的相同映像。 它从Drone主服务器实例接收指令,因此在不需要通用网络访问的情况下,需要在Drone服务之后启动。 它还需要访问Docker的套接字文件以旋转容器来运行实际的构建和测试步骤。 drone-server服务一样,此服务还将自动重新启动并读取/etc/drone/agent.env上的环境文件以进行其他配置。

使用以下Docker Compose文件配置这两个服务。 密切关注文件的YAML格式,因为缩进或格式化的错误可能会导致错误:

/etc/drone/docker-compose.yml
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

完成后,保存并关闭Docker Compose文件。

配置Drone服务器的环境变量文件

接下来,我们需要创建我们在上面的Docker Compose文件中引用的Drone服务器的环境变量文件。

在我们打开文件之前,我们应该生成一个强大的密钥来验证代理和服务器组件。 虽然我们的设置将在同一台服务器上同时拥有这两个组件,但随着测试基础架构的扩展,一个强大的关键是至关重要的。 在命令行中,键入以下内容生成一个键:

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

该命令临时将shell中的语言设置为有限的字符范围。 然后,它从/dev/urandom接收一个随机字节流,并进一步过滤掉任何非字母数字字符。 我们以前65个角色作为关键。

输出将看起来与此类似( 不要复制下面的值!生成自己的! ):

ERmA7xubDvTa8i0wYBlljc9yjT1NJPG7xOlZBwAdMAmBYL4RZE4QngxWcCLowk9KN

将生成的密钥复制到服务器环境文件中使用。

/etc/drone/server.env创建一个新文件,并在文本编辑器中打开它:

sudo nano /etc/drone/server.env

在内部,我们将定义Drone用于连接的环境变量,以启动服务,连接到存储库提供者,并设置帐户授权策略。 您需要先从存储库提供者复制的值正确填写值。

首先,设置DRONE_HOSTDRONE_SECRET值。 DRONE_SECRET设置为在命令行上生成的密钥。 DRONE_HOST设置通知Drone可公开访问的地址。 这应该是让我们加密受保护的域,之前是https://模式说明符:

/etc/drone/server.env
# Service settings
DRONE_SECRET=secret_generated_on_command_line
DRONE_HOST=https://example.com

接下来,我们将配置与我们的VCS提供商的集成,这是我们的案例中的GitHub。 根据您的需求和您的GitHub资产的组织方式,适合您项目的设置可能会有所不同。

我们将通过将DRONE_OPEN设置为false来锁定Drone安装并禁用打开注册。 这将意味着只有在DRONE_ADMIN中DRONE_ADMIN的GitHub帐户名才能登录。

注意 :如果您使用协作者作为GitHub组织,最好将DRONE_OPEN设置为true并将DRONE_ADMIN替换为DRONE_ORGS DRONE_ORGS设置允许您指定一个或多个允许其成员注册的GitHub组织。 Drone将限制对属于这些组的用户的注册。

确保DRONE_ADMIN包含您的GitHub帐户名称。

之后,通过将DRONE_GITHUB设置为true来激活GitHub集成插件。 然后,当我们注册Drone应用程序时,我们将将DRONE_GITHUB_CLIENTDRONE_GITHUB_SECRET设置为从GitHub OAuth应用程序页面复制的密钥:

/etc/drone/server.env
# Service settings
DRONE_SECRET=secret_generated_on_command_line
DRONE_HOST=https://example.com

# Registration settings
DRONE_OPEN=false
DRONE_ADMIN=sammytheshark

# 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将与sever.env文件中的sever.env相匹配。

DRONE_SERVER设置将配置代理如何连接到Drone服务器组件。 它将以一个wss://协议前缀开始,以指示连接将使用加密的Web套接字,后跟Drone服务器的域名,Postfix为/ws/broker URI:

/etc/drone/agent.env
DRONE_SECRET=secret_generated_on_command_line
DRONE_SERVER=wss://example.com/ws/broker

完成后保存并关闭文件。

配置Drone系统单元文件

现在我们的配置文件已经到位,我们可以定义一个systemd单元文件来管理Drone服务。

/etc/systemd/system目录中打开一个新的.service文件来配置服务:

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

内贴粘贴以下内容:

/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

第一部分告诉systemd在Docker和Nginx可用之后启动此服务。 第二部分告诉init系统在发生故障时自动重新启动服务。 然后,它使用Docker Compose和我们之前创建的配置文件定义启动和停止Drone服务的命令。 最后,最后一节定义了如何使服务在启动时启动。

完成后保存并关闭文件。

在我们启动Drone服务之前,我们必须配置Nginx。 Drone代理需要能够连接到Drone服务器,并且连接依赖于Nginx代理到位。

将Nginx配置到Drone的代理请求

接下来,我们需要将Nginx的配置修改为代理服务器的请求。

首先找到处理您的Let's Encrypt-protected域的服务器块配置。 通过键入以下命令,在所有启用的服务器块中搜索server_name属性:

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;

在上面的输出中,在/etc/nginx/sites-enabled/default文件中定义域名(在这种情况下为example.com )。 您将要编辑与您的域名关联的文件(第一列)。

有可能你也可能看到这样的东西:

/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 _; 代表服务器块意味着作为回退机制。 “_”主机说明符是无效的主机,所以它永远不会匹配。

在配置中,这些配置与设置default_server选项的listen指令配对,以便当请求的主机与任何其他定义的服务器块不匹配时,该块作为默认值。 如果找不到与您的域名匹配的server_name定义,则应该使用定义这些后备块的文件。

在您的文本编辑器中打开与您的域最佳关联的文件:

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

在内部,我们将从现有server块之外添加两个部分开始:

在/ etc / nginx的/启用的站点 - /默认
upstream drone {
    server 127.0.0.1:8000;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    . . .

第一个块配置一个名为drone的上游位置,我们可以在其中代理请求。 server指令定义了如何连接到将在端口8000上运行的Drone服务。

第二个块基于$http_upgrade变量的值设置一个名为$connection_upgrade的用户定义变量,当接收到“升级”HTTP头时,Nginx变量设置。 如果收到升级标头,Nginx将设置$connection_upgrade变量进行upgrade 如果没有,它会将其设置为close 这些变量允许我们在代理WebSocket请求时设置正确的头文件。

接下来,使用listen 443指令查找server块。 使用以下指令替换location /块的内容。 确保从该块中注释掉或删除任何现有配置,以避免冲突:

在/ etc / nginx的/启用的站点 - /默认
. . .
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行告诉Nginx proxy_pass该块传出的所有流量传递到我们之前定义的upstream 接下来,我们从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服务将在Docker和Nginx服务可用后启动。

登录Drone以授权访问您的存储库

现在Drone已启动并运行,我们可以登录到Web界面并授权应用程序使用我们的GitHub帐户。

在您的网络浏览器中访问服务器的域名以查看Drone Web界面:

https://example.com

首次访问时,系统将提示您登录:

Drone初次访问

点击登录 ,使用您的GitHub帐户使用OAuth向Drone进行身份验证。 如果您当前没有登录到GitHub,您将被首先登录到GitHub。

之后,系统将提示您允许Drone访问您的GitHub帐户:

Drone允许通过GitHub访问

查看所请求的权限并作出任何调整后,单击授权用户名按钮授权Drone。

您将被重定向回您的Drone服务器:

Drone登录

从这里,您可以激活并配置您的存储库,以自动测试您的代码。

结论

在本指南中,我们将Drone设置为我们的GitHub项目的持续集成和传递服务器。 我们将Drone服务器配置为中心枢纽,以委托工作,处理身份验证,并从我们的存储库中监听更改。 我们还配置了可以运行测试和管理容器的Drone代理。 在所有这些之前,我们将Nginx配置为安全的反向代理。

当您准备好设置“Drone”以自动针对存储库运行测试时,请查看“ Drone”文档 ,了解如何使用测试程序定义.drone.yml文件。