上一次我们使用
还需要一个自动构建工具来解放生产力,这里我推荐使用
为什么选用
相对来说主流的
废话少说,直接开搞~
这里我的服务器环境使用的是最新的
1 安装 Gitea
Gitea
2 安装 Drone
新版的
2.1 Gitea 创建 OAuth2 应用程序
我们进入
来创建一个
这里的重定向
创建成功后就可以拿到客户端
2.2 创建共享密钥
这里我们还需要创建一个共享密钥来供
我们可以使用
$ openssl rand -hex 16
da7fb75c68106b563100bec5ce166b72
2.3 安装 Docker Compose
这里我使用
Docker Compose
安装过程可参考:https://www.runoob.com/docker/docker-compose.html
2.4 编写 docker-compose.yml 文件
这里我们通过使用 Docker Compose 来构建并启动 Drone
$ mkdir drone $ cd drone $ vim docker-compose.yml
在配置文件中,我们设置 docker-compose.yml 的格式为 3 号版本,定义以下两个
- Drone Server:使用
drone/drone:1
版本镜像,将 drone 容器的 80 端口映射到宿主机的 7079 端口。映射容器内 /data
目录到宿主机的/data/drone
目录,以便 drone 可以保留数据。配置服务自动重新启动,并配置构建 drone 所需的环境变量。 - Docker Runner:使用
drone/drone-runner-docker:1
版本镜像,将 docker 启动句柄挂载到容器/var/run/docker.sock
文件中,以便 drone 可以使用 docker-runner 来执行镜像构建任务。环境变量中需要配置 drone server 的端口协议以及共享密钥,以便与 server 进行通信。
具体配置可参考如下配置:
version: '3'
services:
# 容器名称
fan-drone-server:
# 构建所使用的镜像
image: drone/drone:1
# 映射容器内 80 端口到宿主机的 7079 端口
ports:
- 7079:80
# 映射容器内 /data 目录到宿主机的 /data/drone 目录
volumes:
- /data/drone:/data
# 容器随 docker 自动启动
restart: always
environment:
# Gitea 服务器地址
- DRONE_GITEA_SERVER=https://git.ffis.me
# Gitea OAuth2 客户端 ID
- DRONE_GITEA_CLIENT_ID=aaaaaaaaaaa-8888-8888-8888-fffffffffffff
# Gitea OAuth2 客户端密钥
- DRONE_GITEA_CLIENT_SECRET=aaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbffffffff
# drone 的共享密钥
- DRONE_RPC_SECRET=asdfsadfasdfsadfsadfasdf
# drone 的主机名
- DRONE_SERVER_HOST=drone.ffis.me
# 外部协议方案
- DRONE_SERVER_PROTO=https
# 创建管理员账户,这里对应为 gitea 的用户名
- DRONE_USER_CREATE=username:noisky,admin:true
fan-docker-runner:
image: drone/drone-runner-docker:1
ports:
- 7080:3000
restart: always
depends_on:
- fan-drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
# 用于连接到 Drone 服务器的协议。该值必须是 http 或 https。
- DRONE_RPC_PROTO=https
# 用于连接到 Drone 服务器的主机名
- DRONE_RPC_HOST=drone.ffis.me
# Drone 服务器进行身份验证的共享密钥,和上面设置一样
- DRONE_RPC_SECRET=asdfsadfasdfsadfsadfasdf
# 限制运行程序可以执行的并发管道数。运行程序默认情况下执行 2 个并发管道。
- DRONE_RUNNER_CAPACITY=2
# docker runner 名称
- DRONE_RUNNER_NAME=fan-docker-runner-1
2.5 构建 drone 和 runner
docker-compose up -d
-d 为后台运行
这里我的
贴出我的
location / {
proxy_pass http://127.0.0.1:7079/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
2.6 打开 drone
到这里如果没有出问题的话
这里我们进行授权后就跳转到
进入
激活后回到
我们可以进去测试钩子,一般是没问题的
到这里我们的
3 配置 Drone 自动构建
drone
简单来说就是
这里我还是构建一个
3.1 本地部署
本地部署主要步骤:
- drone
拉取最新的代码到当前工作目录 - drone
创建 maven/grade 容器,通过指定的构建工具 maven/grade 等将代码编译 / 打包为 jar 包,然后将 jar 包和 Dockerfile 文件复制到挂载的宿主机共享目录中 - drone
创建 ssh 容器,在容器中通过 ssh 连接到宿主机,通过定义好的命令,到 jar 和 Dockerfile 目录中将 jar 包制作构建为镜像,然后通过镜像创建应用容器并运行,期间会删除之前老的应用程序容器和镜像 - drone
创建钉钉通知容器,将构建成功 / 失败的消息通过钉钉机器人通知到管理员
至此本地构建完毕,这个构建步骤是我自己搞的,其优点是所有操作都在本机执行,构建的应用不用经过网络传输,整体部署的速度很快,其缺点是只能单机部署,无法进行分布式多机器部署,如果自己个人单机使用的话推荐使用这种方式,我的测试
编写
在仓库的根目录下创建.drone.yml
配置文件参考如下配置:
# drone 本地构建
kind: pipeline
type: docker
name: MyHelloWorld
# drone 构建步骤
steps:
# 1.maven 打包
- name: maven compile
pull: if-not-exists
image: maven:ibmjava-alpine
volumes:
# maven 构建缓存
- name: cache
path: /root/.m2
# 挂载宿主机的目录
- name: data
path: /home
commands:
# 开始打包 maven 工程
- cd demo
- mvn clean package -Dmaven.test.skip=true
# 将打包后的文件复制到宿主机映射目录
- cp target/*.jar /home
- cp ../Dockerfile /home
# 2. 使用 ssh 访问主机制作镜像并运行
- name: ssh commands
pull: if-not-exists
image: appleboy/drone-ssh:1.5.7
settings:
host: 0.0.0.0
username: root
password:
# 从 drone 仓库配置中秘密空间读取密码
from_secret: ssh_password
port: 22
script:
- echo ======= 暂停容器 =======
- docker stop `docker ps -a | grep springdemo | awk '{print $1}' `
- echo ======= 暂停旧容器和镜像 =======
- docker rm -f `docker ps -a | grep springdemo | awk '{print $1}' `
- docker rmi `docker images | grep springdemo | awk '{print $3}' `
- echo ======= 开始构建新镜像 =======
- cd /data/drone/helloDemo
- docker build -t springdemo:v1 .
- echo ======= 开始部署应用 =======
- docker run -d -p 8188:8180 --name springdemo springdemo:v1
- echo ======= 清理构建文件 =======
- rm -rf *
- echo ======= 部署成功 =======
# 3. 钉钉通知
- name: dingTalk notification
pull: if-not-exists
image: guoxudongdocker/drone-dingtalk:latest
settings:
token:
from_secret: dingtalk_token
type: markdown
message_color: true
message_pic: true
sha_link: true
when:
status: [failure, success]
# 挂载的主机卷,可以映射到 docker 容器中
volumes:
# maven 构建缓存
- name: cache
host:
# path: /tmp/cache/.m2
path: /var/lib/cache
# maven 构建后与宿主机通信的共享目录
- name: data
host:
path: /data/drone/helloDemo
# drone 执行触发器
trigger:
branch:
- master
文件编写完成后,git push.drone.yml
3.2 分布式云部署
云部署主要步骤:
- drone
拉取最新的代码到当前工作目录 - drone
创建 maven/grade 容器,通过指定的构建工具 maven/grade 等将代码编译 / 打包为 jar 包,然后将打包完成后的 jar 移动到根目录,也就是工作目录 - drone
创建 docker 构建容器,将 jar 通过 dockerfile 指定的方式构建为镜像,然后将构建完成的镜像上传到腾讯云 / 阿里云私有仓库中 - drone
创建 ssh 容器,通过 ssh 连接到一个或多个主机,然后批量从私有仓库中拉取最新镜像进行部署 - drone
创建钉钉通知容器,将构建成功 / 失败的消息通过钉钉机器人通知到管理员
这种方式配置较为简单,所有操作都在
不过好在同一服务商的私有仓库都是通过内网进行访问的,访问速度影响可忽略不计;
而且有很大的优化空间,毕竟我们写的代码只有几百
所以可以通过对
这样每次更新的就只有我们写的代码,传输的数据量就很少了,不过这个属于比较高级的应用了,我们这里先不研究了;
云部署主要好处是可以做到分布式部署,多个主机可以从私有仓库中拉取最新镜像,实用性还是很高的。
编写
同样也是在仓库的根目录下创建.drone.yml
参考如下配置:
# drone 云部署
kind: pipeline
type: docker
name: MyHelloWorld
# drone 构建步骤
steps:
# 1.maven 打包
- name: maven compile
pull: if-not-exists
image: maven:ibmjava-alpine
volumes:
# maven 构建缓存
- name: cache
path: /root/.m2
commands:
# 开始打包 maven 工程
- cd demo
- mvn clean package -Dmaven.test.skip=true
# 将打包后的 jar 包移动到 Dockerfile 文件同级目录
- mv target/demo-0.0.1-SNAPSHOT.jar ../demo-0.0.1-SNAPSHOT.jar
# 2.Docker 制作镜像,推送到私有仓库
- name: docker build
image: plugins/docker
pull: if-not-exists
volumes:
- name: docker
path: /var/run/docker.sock
settings:
username: username
password:
from_secret: dockerHub_password
tags:
- latest
repo: ccr.ccs.tencentyun.com/fanfan/hellodemo
registry: ccr.ccs.tencentyun.com
dockerfile: Dockerfile
# 3. 使用 ssh 访问主机运行最新版容器
- name: ssh commands
pull: if-not-exists
image: appleboy/drone-ssh:1.5.7
settings:
host: 49.234.106.44
username: root
password:
from_secret: ssh_password
port: 22
script:
- echo ======= 暂停容器 =======
- docker stop `docker ps -a | grep springdemo | awk '{print $1}' `
- echo ======= 暂停旧容器 =======
- docker rm -f `docker ps -a | grep springdemo | awk '{print $1}' `
- echo ======= 开始部署应用 =======
- docker run -d -p 8188:8180 --name springdemo --restart=always ccr.ccs.tencentyun.com/fanfan/hellodemo:latest
- echo ======= 部署成功 =======
# 4. 钉钉通知
- name: dingTalk notification
pull: if-not-exists
image: guoxudongdocker/drone-dingtalk:latest
settings:
token:
from_secret: dingtalk_token
type: markdown
message_color: true
message_pic: true
sha_link: true
when:
status: [failure, success]
# 挂载的主机卷,可以映射到 docker 容器中
volumes:
# maven 构建缓存
- name: cache
host:
# path: /tmp/cache/.m2
path: /var/lib/cache
- name: docker
host:
path: /var/run/docker.sock
# drone 执行触发器
trigger:
branch:
- master
编写好部署的配置文件,推送到仓库中,drone
首次部署的速度可能略慢,我这里用了
部署成功后的钉钉通知页面
4 资源占用
Gitea
可以看到总占用也不到
自动部署一旦配置好了,所有的编译
感觉应该是反向代理配置有问题,你 docker 容器为什么映射到 80 和 443 端口,这应该和 nginx 的端口是冲突了的; drone 的 docker 容器映射到了 7079 80 和 443 端口是指向 nginx 然后 nginx 再将请求转发到 7079 的
我搭建的时候是把
大佬,可以帮忙把这条留言删了吗,因为我发现涉及到了 id,域名,SECRET。我自己再研究研究吧,官网的 https://docs.drone.io/server/provider/github/ 和 https://docs.drone.io/runner/docker/installation/windows/ 参考配置太坑了
ok 已删除 官方的文档确实挺坑的 毕竟是比较冷门的方案 没有什么参考资料 只能自己摸索 不过配置好了应该还是能用的 你再摸索摸索吧
我可以了,之前一直不行原来不是配置的问题,是我用一台 Nginx 服务器反代我本地的 localhost,服务器将 localhost 认为是自己的 localhost 所以连不上。我好蠢 
我的 nginx 和 docker 不在同一台机器上,所以 docker drone 的 127.0.0.1:7079 不能反代到 nginx 的域名上吧?
Hi Noisky, Nginx 服务器上运行的 docker-compose 吗?然后反代了 Nginx 服务器可以访问的 127.0.0.1:7079 到域名?
请问你是在
7079 是 docker 容器 drone 的端口,nginx 将域名的访问反代到 drone 上