jenkins、circleci、travis 或 Gitlab CI 皆為目前暫知名的 CI/CD 服務,各自缺點也不言而喻…
過於肥大、收費略高(?)、速度不夠快執問題…
此時使用 go language 開發的 Drone 就出現啦,完全 docker 容器化的運行方式讓整個 CI / CD 流程、速度提升到一個新的境界(誇張 🤪)
在開始前~先簡單瞭解 Drone 的執行流程~
從下面的流程圖可以看出整體動作的起源在於 Git
可以是 github, gitlab, bitbucket 或是任一自架的 Git 服務都可以~
其重點是: Git 服務會發送 webhook 至你自己架設的 Drone 服務
安裝 Drone 最重要的一步!
您必須有一個開放、外部可連線的 domain 或 IP
從上文的 Drone 執行流程得知 git push 之後的觸發動作 (webhook) 是需要一個開放網址讓 git 服務進行通知。
沒有 domain 或 IP 的人可以參考使用 ngrok 服務
ngrok 可以很快速的將本機 port 開放至 internet (將提供一個亂數網址)
可以參考 Bo-Yi 大神的 Drone 教學影片 & 文章
『用五分鐘安裝好 Drone 搭配 GitHub 自動化環境』
https://www.youtube.com/watch?v=-U2EXs0tmN0
https://blog.wu-boy.com/2020/02/install-drone-with-github-in-five-minutes/
上面兩篇文章,你就可以離開 Cola 教室了 XD
官網文件也有簡單的 docker + drone + github 的設定教學
https://docs.drone.io/server/provider/github/
開始前~ 先申請 github oauth app
Github >Settings >Developer settings > OAuth Apps
取得
Client ID 與 Client Secret
注意: 設定 url, 和 callback url
Drone 是一個以 docker 容器為主的服務,安裝上當然也是首選 docker 囉~
因為我還有其它 web 服務,希望所有 web 服務的露出都透過 nginx 處理,
所以我還另開了 nginx,不讓 drone web UI直接曝露。
如果使用 ngork 可以將 nginx servcie 的部分刪掉、不使用~
(對 docker 沒概念的人可以參考 https://github.com/cscolabear/docker-dev)
docker-compose.yml example
version: '3.7'
services:
nginx:
hostname: docker-nginx
image: fholzer/nginx-brotli:v1.18.0
ports:
- 80:80
- 443:443
volumes:
- ${VOLUMES_DRIVER}:/var/www:delegated
- ./Logs:/var/log/nginx:delegated
- ./Dockerfiles/nginx/sites-enabled:/etc/nginx/sites-enabled:ro
depends_on:
- drone-server
networks:
- app_net
drone-server:
image: drone/drone:1
ports:
- 8080:80
volumes:
# 設定本機的 Database 目錄存放 drone 服務相關資料
- ./Database/drone:/data
environment:
- DRONE_SERVER_HOST=${DRONE_SERVER_HOST}
- DRONE_SERVER_PROTO=${DRONE_SERVER_PROTO}
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
- DRONE_USER_CREATE=${DRONE_USER_CREATE}
- DRONE_USER_FILTER=${DRONE_USER_FILTER}
# GitHub Config
- DRONE_GITHUB_SERVER=https://github.com
# 至 github OAuth Application 申請、取得 id 與 secret
- DRONE_GITHUB_CLIENT_ID=${DRONE_GITHUB_CLIENT_ID}
- DRONE_GITHUB_CLIENT_SECRET=${DRONE_GITHUB_CLIENT_SECRET}
# deubgu 時可以拿掉下面三個註解
# - DRONE_LOGS_DEBUG=true
# - DRONE_LOGS_PRETTY=true
# - DRONE_LOGS_COLOR=true
networks:
- app_net
drone-runner:
image: drone/drone-runner-docker:1
restart: always
depends_on:
- drone-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 128M
restart_policy:
condition: on-failure
environment:
- DRONE_RPC_HOST=${DRONE_RPC_HOST}
- DRONE_RPC_PROTO=${DRONE_RPC_PROTO}
- DRONE_RPC_SECRET=${DRONE_RPC_SECRET}
- DRONE_RUNNER_CAPACITY=1
networks:
- app_net
networks:
app_net:
driver: "bridge"
上面 yml 內看見類似… ${VOLUMES_DRIVER}
這是讓 docker-compose 由 .env 讀入的環境變數
下面為 .env 的內容 (example)
# 本機電腦裡的 Web 專案目錄位置
VOLUMES_DRIVER="~/my_web_projects/"
# 使用 ngrok 提供的亂數 domain
DRONE_SERVER_HOST= apo2r385963.ngrok.io
# ngrok 預設提供 https
DRONE_SERVER_PROTO=https
# 自行至 command line 輸入 openssl rand -hex 16,將生成的內容復制貼上
DRONE_RPC_SECRET=ax1234e8948s4cbcirbb4b4ifn29932nd
# drone runner: 直接使用 drone server 的 docker container name
DRONE_RPC_HOST=drone-server
DRONE_RPC_PROTO=http
# 使用前面動作在 github 申請來的 oauth app id 與 secret
DRONE_GITHUB_CLIENT_ID=dxxxxxxxxxxx8
DRONE_GITHUB_CLIENT_SECRET=2xxxxxxxxxxxxxxxxxxx5
# 設定 drone 使用者權限(也可以直接參考下一個章節~)
DRONE_USER_CREATE=username:cscolabear,admin:true
DRONE_USER_FILTER=cscolabear,cola_team,colapig
上面 .env 裡設定的…
DRONE_USER_CREATE: 設定 id 是 cscolabear 的使用者為 admin
DRONE_USER_FILTER: 設定只有哪些 user id 或 organization 可以使用
多組情況下的設定為
e.g. DRONE_USER_FILTER=cscolabear,cola_team,colapig
未授權的使用者將收到這樣的訊息~Login Failed. User must be a member of an approved organization
上述的設定檔、參數都處理後之後,有幾種方式啟動 Drone 服務…
# 直接啟動,初期 debug 可以用這個方式查看 docker log
$ docker-compose up
# 啟動並將 docker 移到背景
$ docker-compose up -d
# 使用 ~/my-docker-compose.yml 這個設定檔啟動
$ docker-compose -f ~/my-docker-compose.yml up
# 啟動後,也可以用下面指令查看 drone server 的執行 log
$ docker-compose logs drone-server
如果想使用 Nginx 反向代理 Drone 可以參考下面設定
ngork 的使用者可以直接略過這個部份
在前面步驟~
docker-compose.yml 設定了 nginx (volumes) sites-enabled 目錄
其目錄下新建一個 nginx conf
drone.conf example
server {
# listen 80;
# listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name local.drone;
access_log /var/log/nginx/drone.workxplay.net.access.log main;
error_log /var/log/nginx/drone.workxplay.net.error.log;
ssl_certificate /etc/nginx/ssl/default.crt;
ssl_certificate_key /etc/nginx/ssl/default.key;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://drone-server;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
設定好 nginx conf 後重新啟動 nginx Service
$ docker-compose restart nginx
# or
$ docker-compose -f ~/my-docker-compose.yml restart nginx
在編寫 .drone.yml 前,先設定 secret 值
drone secret 用於 .drone.yml 內,一些不想曝光或是隨時抽換的變數。
多數的 .drone.yml 都是開放的,如果把主機 IP 或是 ssh key 金鑰等存放在開放的 .drone.yml 其實不太恰當。
將這些不想曝光的值設定為 secret 後,可以在 .drone.yml 裡像直接引用~
針對各別Repository 做設定時可以使用 web ui (Per Repository)
https://docs.drone.io/secret/repository/
Repositories >[your repository] >SETTINGS >Secrets
接著移到 git repo,在專案裡加入 .drone.yml
設定 drone 的執行動作
在編寫 .drone.yml 時要注意、新舊版差異喔(本文為 drone 1.x)
step 為 drone 執行流程
.drone.yml example
kind: pipeline
type: docker
name: default
clone:
depth: 1
steps:
- name: node
image: node:12.17-slim
commands:
- npm install
- npm run dev
when:
branch:
- master
- name: rsync
image: drillster/drone-rsync
settings:
hosts:
from_secret: HOST
user:
from_secret: SSH_USER_NAME
key:
from_secret: USER_KEY
source: ./dist/
target:
from_secret: TARGET_PATH
recursive: true
delete: true
args: "--no-o --no-g -v"
# script:
# - ls -al
when:
branch:
- master
- name: slack
image: plugins/slack
settings:
webhook:
from_secret: SLACK_WEBHOOK
channel: drone-workxplay
link_names: true
username: "Drone Bot"
icon_emoji: ":robot_face:"
when:
status: [ success, failure ]
template: >
{{#success build.status}}
✅ build #{{build.number}} succeeded. Good job.
`{{repo.name}}/{{build.branch}}`
{{build.link}}
{{else}}
❌ build #{{build.number}} failed. Fix me please.
`{{repo.name}}/{{build.branch}}`
{{build.link}}
{{/success}}
secret 的呼叫方法
user:
from_secret: SSH_USER_NAME
如果不使用 secret
user: cola
或
user: "cola bear"
都設定完成後將 .drone.yml 加入想處理的 Git repo 並 git push~
接著進入 drone web ui,可以看到 drone 己經開始處理任務了~
最後~ 來看一下 Drone CI/CD 的優點和缺點
優點 / pros:
缺點 / cons:
Q. Git push 但是 Drone 沒有反應
A. 檢查 oauth client id, secret 都正確
再檢查 webhook 是否有接通
github 目標 repo >settings >Webhooks
檢查 url 是否正確
參考內容:
錯誤追蹤、回報非常重要,看到的錯誤才知道怎麼修。現今 PHP 流行的 Laravel 有很好的 Error Tracking, Error Handling。但 plain PHP 怎麼辦呢? 在 production 為了安全考量會設定…
網頁壓縮技術中 gzip 很好用,deflate 己經過時,但你聽過 brotli 嗎? 有著比 gzip 更好、更快的壓縮效率。看起來利大於弊有什麼不用他的理由嗎?簡單從優、缺點來看 brotli!到底 brotli 布羅特利是什麼、如何設定呢。 目前大多的 web server…
為什麼要讓本機使用 Docker 內 PHP? 情境... docker 容器內用的是 PHP 7.4 但你的開發本機還在跑 PHP 5.6 或是更舊,因為 dockerize 的關係會將所有相關環境都轉移到…
為什麼你需要密碼管理工具現代人一天下來需要輸入多少組密碼,工作與生活己經和密碼密不可分! 除了足夠全安的密碼,密碼記錄、儲存的方式又足夠安全嗎?密碼管理工具可以帶來什麼幫助呢? 為什麼你需要密碼管理工具 資安問題!!大多人說著沒做壞事不怕被偷資料、監聽。嚴重曝露出現代人的基本科技素養的低落和無知 🤯 密碼的使用無所不在!! 行動裝置的普及,APP 、手機遊戲、銀行帳戶所有和生活相關的東西都需要密碼!!facebook, line 只要打開 APP 也會輸入密碼只是他是自動輸入、一般情況不可視 (auth token) 一般人最常發生的密碼資安問題…
mysql 資料表分區 mysql table partition 從架構上調整 mysql 的查詢效率。mysql DB 的優化可以簡單也能複雜,除了調整設定值。也可以透過水平分割(Horizontal Partitioning)、垂直分割(Vertical Partitioning) 分庫或分表將資料分散儲存減少資料搜尋、group by 時的效能消耗。拆開批次處理,理論上效率都會變好,本文就水平分割的…
透過 vscode Debug 利用中斷點 (breakpoints) 讓開發、偵錯更聰明。 加快除錯速度,而不是用傳統的 console log 方式查看變數、物件內容找問題。 本篇教你如何用 vscode + node +…