Drone(轻量持续部署服务)

把重复的手动部署工作, 利用Drone工具自动处理整套部署步骤. 「自动执行.sh脚本

执行的步骤大概如:

  • 场景1:

    • 打包: 拉取代码 –> 更新依赖(npm i) –> 构建项目(build)
    • 部署: 删除旧的资源包 –> 替换新构建的资源包
  • 场景2(Docker):

    • 打包: 拉取代码 –> 更新依赖(npm i) –> 构建项目(build) –> 打包镜像(DockerFile) –> 推送到镜像仓库
    • 部署: SSH连接到服务器 –> 拉取新镜像 –> 停止和移除旧容器 —> 启动新容器

   Drone安装


  Drone由 Server(服务器) 和 Runner(执行器) 组成

  • Server

    • 连接到代码仓库 (GitHub、GitLab、Gogs、Gitea、Gitee、…)
    • 提供了Web管理界面
    • 管理 Runner
  • Runner(执行持续部署操作的服务)

    • 执行时会轮询 Server 来确定执行的操作

准备工作

在Gitea上为Drone创建OAuth认证登陆

  

  1. 输入信息, 点击保存

  2. 记录生产的信息

    1. 客户端ID: e5c409df-36be-4cb6-aa25-151325754c3f
    2. 客户端密钥: x8Uu2gHyjjhJbbLf2VltvwfMFF3mVTLk0xiHdE9bJjy3

生成 Drone Server 和Drone Runner 通信密钥 「共享密钥」

1
openssl rand -hex 16

通过docker-compose安装Drone

  • 配置 docker-compose 文件
1
2
3
4
5
6

mkdir /home/git/drone
cd /home/git/drone


vi docker-compose.yml
  • docker-compose.yml 配置:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
version: '3'
services:
  
  fan-drone-server:
  
    image: drone/drone:2
  
    ports:
      - 3222:80
  
    volumes:
      - ./data:/data
  
    restart: always
    environment:
    
      - DRONE_GITEA_SERVER=http://124.222.237.29:3333
    
      - DRONE_GITEA_CLIENT_ID=e5c409df-36be-4cb6-aa25-151325754c3f
    
      - DRONE_GITEA_CLIENT_SECRET=x8Uu2gHyjjhJbbLf2VltvwfMFF3mVTLk0xiHdE9bJjy3
    
      - DRONE_RPC_SECRET=efb695f7109af80ff7582768dd07c3ae
    
      - DRONE_SERVER_HOST=124.222.237.29:3222
    
      - DRONE_SERVER_PROTO=http
    
    
      - DRONE_USER_CREATE=username:git,admin:true
    
      - DRONE_GIT_ALWAYS_AUTH=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_RPC_PROTO=http
    
      - DRONE_RPC_HOST=124.222.237.29:3222
    
      - DRONE_RPC_SECRET=efb695f7109af80ff7582768dd07c3ae
    
      - DRONE_RUNNER_CAPACITY=2
    
      - DRONE_RUNNER_NAME=fan-docker-runner-1

激活仓库

  访问 124.222.237.29:3222 会直接跳转Gitea认证页面

  

  此处省略注册步骤~~~

  进入面版看到gitea中的test1项目, 没有的则点击SYNC同步项目

  

  点击test1项目, 进去setting选项并点击激活按钮激活项目

  

简单测试, 分享常见错误

在test1测试项目, 建立 .drone.yml 文件, 并写入以下内容进行测试

  PS: test1项目 是由vite脚手架, 简单构建出来的ts-react项目

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

kind: pipeline 
type: docker 
name: test 
steps: 
  - name: test 
    image: node:latest 
    commands: 
      - echo 测试drone 
      - pwd 

  正确例子

  • 输出1: 测试drone drone正常执行
  • 输出2: drone执行的绝对路径为 /drone/src

  

错误1: 用户非Gitea管理员用户

  错误效果

  

  正确效果

  

  解决

  确保Gitea用户是管理员用户

  确保docker-compose配置中git用户是Gitea的管理员用户

  • DRONE_USER_CREATE=username:git,admin:true

  PS: 修改配置之后记得重启drone服务

错误2: 不受信任的仓库 untrusted repositories cannot mount host volumes

  错误效果

  

  解决

  确保Trusted选项已勾选

  Settings –> Project Settings –> Trusted

  

错误3: 拉取代码失败 Fatal: could not read Username for

  错误效果

  

  解决

  • 官方解答

  • 方向1:

    • 开启私有仓库选项 「Settings –> Project Visibility –> Public改成Private」
    • 开启认证, docker-compose.yml 中 DRONE_GIT_ALWAYS_AUTH=true 「为true开启认证」
  • 方向2: 验证用户密码是有有错, 如下配置是否错误:

1
2
3

DRONE_GIT_USERNAME=<username>
DRONE_GIT_PASSWORD=<password>

实现 场景一

  • 场景1:

    • 打包: 拉取代码 –> 更新依赖(npm i) –> 构建项目(build)
    • 部署: 删除旧的资源包 –> 替换新构建的资源包

  知识点:

  • 将宿主机的卷轴映射(挂载)进Drone执行器里面 「公共卷轴」; 简要说明 Drone 提供的Volume

    • Host Volume:数据挂载到宿主机上与宿主机公用卷轴
    • Temporary Volume: 临时卷轴, 不同Step「步骤」共享, Pipeline「管道」 执行完毕后清除.
  • 使用Nginx简单部署打包产物

  • 拓展: 使用 appleboy/drone-scp 上传文件到另外的服务器

  • 拓展: 使用 Setting --> Secrets配置 储存敏感数据

  前提条件:

  • 有可以正常打包访问的前端项目(本例子是由vite脚手架, 简单构建出来的ts-react项目)
  • 部署服务已安装nginx, 并可以正常使用

drone和部署的服务在同一台主机

  PS: 在同一台部署服务器, 直接共享卷轴, 就可以完成打包并部署

  重要说明:

  • 通过与宿主机共享Volume, 缓存node_modules 「每次构建都是全新的drone-runner-docker容器, 共享卷轴可以省去install时间」
  • drone服务和部署服务器同一台主机, 而主机上又有nginx. 通过共享目录, 达到直接部署的目的

  项目的.drone.yml 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

kind: pipeline 
type: docker 
name: build-test1 


volumes: 
  - name: node_modules 
  
    host: 
    
      path: /home/gite/drone/cache/node_modules
  - name: web_build_dir
    host:
      path: /usr/share/nginx/test1

steps:
  - name: build-project 
    image: node:16.13.1 
    depends_on: [clone] 
    volumes: 
      - name: node_modules 
        path: /drone/src/node_modules 
      - name: web_build_dir
        path: /drone/src/dist
  
    commands: 
      - pwd 
      - npm config set registry https://registry.npm.taobao.org 
      - npm install 
      - npm run build 
  • 检查构建物 ll /usr/share/nginx/test1
  • 浏览器访问查看效果

drone和部署的服务不在同一台主机

  重要说明:

  • 配置secrets, drone配置界面 Setting --> Secrets配置 储存敏感数据

  • 同上, 共享node_modules

  • drone官网插件

  • 使用 appleboy/drone-scp 镜像进行上传文件 地址

  • 官网还有一个cschlosser/drone-ftps插件用ftp上传, 试了半天愣是没成功

    • 官网插件的文档和github 的文档不是一样的「估计是镜像和仓库应该就是不一样的」
    • 一直在运行~~
    • 感觉需要ftp还是自己写个sh吧

  项目的.drone.yml 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

kind: pipeline 
type: docker 
name: build-test1 


volumes: 
  - name: node_modules 
  
    host: 
    
      path: /home/gite/drone/cache/node_modules
  
  
  
  
    

steps:
  - name: build-project 
    image: node:16.13.1 
    depends_on: [clone] 
    volumes: 
      - name: node_modules 
        path: /drone/src/node_modules 
    
      
  
    commands: 
      - pwd 
      - npm config set registry https://registry.npm.taobao.org 
      - npm install 
      - npm run build 
    

  - name: deploy-project 
    image: appleboy/drone-scp
    depends_on: [build-project] 
    settings:
    
      host: o2packs.com 
      username: 
        from_secret: deploy_username 
      password: 
        from_secret: deploy_password
    
    
      source:  
      
        - ./dist
    
      target: /usr/share/nginx/test1
    
      rm: true 
      port: 22
      command_timeout: 2m

实现 场景二(Docker)

  • 场景2(Docker):

    • 打包: 拉取代码 –> 更新依赖(npm i) –> 构建项目(build) –> 打包镜像(DockerFile) –> 推送到镜像仓库
    • 部署: SSH连接到服务器 –> 拉取新镜像 –> 停止和移除旧容器 —> 启动新容器

  知识点:

  • drone多个pipeline使用
  • 利用Dockerfile打包docker镜像
  • 利用 appleboy/drone-ssh 插件远程到部署服务器部署项目

  前提条件:

  • 有可以正常打包访问的前端项目(本例子是由vite脚手架, 简单构建出来的ts-react项目)
  • 部署服务器已安装docker和docker-compose
  • 部署服务器允许密码登陆 「PS: 若使用SSH, 请参考官网修改

  项目的.drone.yml 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
kind: pipeline 
type: docker 
name: build-test1 


volumes: 
  - name: node_modules 
    host: 
      path: /home/gite/drone/cache/node_modules





steps:
  - name: build-project 
    image: node:16.13.1 
    depends_on: [clone] 
    volumes: 
      - name: node_modules 
        path: /drone/src/node_modules 
  
    commands: 
      - pwd 
      - npm config set registry https://registry.npm.taobao.org 
      - npm install 
      - npm run build 

  - name: build-image 
    image: plugins/docker 
    depends_on: [build-project] 
    settings: 
      username: 
        from_secret: docker_username
      password: 
        from_secret: docker_password
      dockerfile: deploy/Dockerfile 
      repo: soulweapon/test1 

---


kind: pipeline
type: docker
name: deploy

depends_on: 
  - build-test1

clone:
  disable: true 

steps:
  - name: deploy-project
    image: appleboy/drone-ssh
    settings:
      host: o2packs.com
      username: 
        from_secret: deploy_username 
      password: 
        from_secret: deploy_password
      port: 22
      command_timeout: 2m
      script:
        - echo ==-----==开始部署==-----==
        - docker pull soulweapon/test1:latest
        - docker-compose -p test1 down
      
        - docker-compose -f /home/ubuntu/compose-file/test1.yml -p test1 up -d
      
        - docker rmi $(docker images | grep test1 | grep none | awk '{print $3}')
        - echo ==-----==部署成功==-----==

  必备文件1「deploy/Dockerfile」:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11

FROM nginx:latest


COPY ./dist /usr/share/nginx/html


COPY ./deploy/nginx.conf /etc/nginx


EXPOSE 80

  必备文件2「deploy/nginx.conf」:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
events {
  worker_connections 1024;
}

http {
  include mime.types;
  default_type text/html;
  sendfile on;
  keepalive_timeout 65;
  charset utf-8;
  error_log /var/log/nginx/error.log;
  access_log /var/log/nginx/access.log;

  server {
    listen 80;

    location / {
      root /usr/share/nginx/html;
      index index.html index.htm;
      try_files $uri $uri/ /index.html;
    }

  
  
  
  
  
  
  
  
  
  }
}

  必备文件3「部署服务器 - /home/ubuntu/compose-file/test1.yml」:

1
2
3
4
5
6
7
8
9
version: '3.0'

services:
  nginx: 
    image: soulweapon/test1:latest
    container_name: test1_web 
    restart: always 
    ports: 
      - "8088:80"