---
# System prepended metadata

title: Drone的網路-CICD平台+compose yaml腳本

---

# Drone的網路-CICD平台+compose yaml腳本

終於，我們來到了整個系列的起點：CICD全容器化作業的野望。

曾經使用過Azure DevOps、Jenkins、Gitlab等CICD工具，也有一說是使用Dockerfile與Docker compose yaml來做CICD，都算是太過複雜跟難入門，而我的目標就是每個編譯環境我都要在同一個HOST做出來，彼此不受影響，甚至用過就拋棄，Jenkins跟Docker也有整合，但Jenkins也太肥大。

某次意外看到Drone CI這個工具，也就是容器原生的CICD工具，就想說，這應該就是我想要的了。

一開始用了gogs+drone，很明顯gogs是比較沒有維護的專案，所以遇到問題比較找不到資源，所以本次就改用gitlab+drone，經歷過幾次錯誤與排除，終於完整上線。

我這邊先講已經完成的CI pipeline:

![](https://hackmd.io/_uploads/HJ8FWV0eT.png)

1. 先建立CI平台，包含gitlab,drone,drone runner，gitlab跟drone在寫成docker compose之前都有先run過，建立了一些檔案跟key

- 啟動gitlab,drone，runner因為有相依性，等前兩個服務ok再啟動

```
version: "3"
name: cicd
services:
 gitlab:
    image: gitlab/gitlab-ce:16.4.1-ce.0
    restart: always
    networks:
     ap_net:
       ipv4_address: 172.18.0.2
    ports:
      - 8080:80
      - 8443:443
      - 22:22
    volumes:
      - "/home/ted/project/gitlab/config:/etc/gitlab"
      - "/home/ted/project/gitlab/logs:/var/log/gitlab"
      - "/home/ted/project/gitlab/data:/var/opt/gitlab"
 drone:
    image: drone/drone:2.20.0
    volumes:
     - "/home/ted/project/drone:/data"
    environment:
     - DRONE_GITLAB_SERVER=http://172.18.0.2
     - DRONE_GITLAB_CLIENT_ID=xxx
     - DRONE_GITLAB_CLIENT_SECRET=xxxxx
     - DRONE_RPC_SECRET=xxxx
     - DRONE_SERVER_HOST=172.18.0.4
     - DRONE_SERVER_PROTO=http
     - DRONE_USER_CREATE=username:root,admin:true
    depends_on:
     gitlab:
      condition: service_healthy
    ports:
     - 80:80
     - 8000:443
    networks:
     ap_net:
       ipv4_address: 172.18.0.4
 sonarqube:
    image: sonarqube:8.9.10-community
    volumes:
      - "/home/ted/project/sonarqube/data:/opt/sonarqube/data"
      - "/home/ted/project/sonarqube/logs:/opt/sonarqube/logs"
      - "/home/ted/project/sonarqube/extensions:/opt/sonarqube/extensions"
    ports:
     - 9000:9000  
    networks: 
     ap_net:
       ipv4_address: 172.18.0.6
 portainer:
    image: portainer/portainer-ce:2.19.1-alpine
    volumes:
     - /var/run/docker.sock:/var/run/docker.sock
    ports:
     - 8001:8000
     - 9443:9443
networks:
    ap_net:
     external: true
```

- 啟動runner

```
version: "3"
name: runner
services:
 drone-runner:
    image: drone/drone-runner-docker:1
    volumes:
     - /var/run/docker.sock:/var/run/docker.sock
    ports:
     - 3000:3000
    environment:
     - DRONE_RPC_PROTO=http
     - DRONE_RPC_HOST=172.18.0.4
     - DRONE_RPC_SECRET=xxxx
     - DRONE_RUNNER_CAPACITY=2
     - DRONE_RUNNER_NAME=my-first-runner
     - DRONE_RUNNER_NETWORKS=ap_net
     - DRONE_USER_CREATE=username:root,admin:true
    networks: 
     ap_net:
       ipv4_address: 172.18.0.5
networks:
    ap_net:
     external: true
```

2. 撰寫.drone.yml並且push上去gitlab

```
kind: pipeline
name: default

steps:
- name: package&scan
  image: docker:dind
  volumes:
  - name: dockersock
    path: /var/run/docker.sock
  commands:
  - docker compose -f docker-compose-build.yaml up
- name: sbom scan
  image: docker:dind
  volumes:
  - name: dockersock
    path: /var/run/docker.sock
  commands:
  - docker compose -f docker-compose-grype.yaml up
volumes:
- name: dockersock
  host:
    path: /var/run/docker.sock
```

總共兩個步驟，我用兩支compose yaml來寫：

- docker-compose-scan.yaml

```
version: "3"
name: scan
services:
 sonarqube:
    image: sonarqube:8.9.10-community
    volumes:
      - "/home/ted/project/sonarqube/data:/opt/sonarqube/data"
      - "/home/ted/project/sonarqube/logs:/opt/sonarqube/logs"
      - "/home/ted/project/sonarqube/extensions:/opt/sonarqube/extensions"
    ports:
     - 9000:9000  
    networks: 
     ap_net:
       ipv4_address: 172.18.0.6
networks:
    ap_net:
     external: true
```

- docker-compose-build.yaml

```
version: "3"
name: maven
services:
 maven:
    image: maven:3.9.4-eclipse-temurin-8-alpine
    volumes:
      - "/home/ted/project/xxx/source:/usr/src/mymaven"
      - "/home/ted/project/xxx/m2:/root/.m2"
    working_dir: /usr/src/mymaven
    command: mvn clean package sonar:sonar   -Dsonar.projectKey=xxx  -Dsonar.host.url=http://sonarqube:9000   -Dsonar.login=xxx 
    networks: 
      - ap_net
networks:
    ap_net:
     external: true
```

- docker-compose-grype.yaml

```
version: "3"
name: grype
services:
 grype:
    image: anchore/grype:v0.69.1
    volumes:
     - "/home/ted/project/grypedb:/cache"
     - "/home/ted/project/xxxx/source/target:/tmp"
    environment:
     - GRYPE_DB_CACHE_DIR=/cache
     - GRYPE_DB_AUTO_UPDATE=false
    command: /tmp/web.war -v --only-fixed

```

進入drone就可以看到，只要git push，就會自動啟動pipeline。

![](https://hackmd.io/_uploads/H1LdU40la.png)

可以看到sonarqube的掃描紀錄
![](https://hackmd.io/_uploads/ry9Xw4Aea.png)

也可以進入drone去看grype掃描的結果。

後續可能再增加gate機制，如sonarqube掃描不通過，就run不下去，grype掃描war有critical也可以不run下去，或是跟webhook整合，通知執行結果。
