又看到一間網路平台公司從 Node.js 跳到 Golang 了。ScaleDrone 是一間提供了 websocket 服務的公司,讓 web 可以透過 ScaleDrone 即時將訊息傳播到各種瀏覽器,但是今天看到 ScaleDrone 即將把後端平台使用的語言從 Node.js 轉換到 Golang,為什麼要轉語言呢,官方提到大量的 Websocket 連線,讓伺服器記憶體快吃不消了,然而 ScaleDrone 用 Go 語言來實際測試,發現記憶體不但沒有增加,反而還降低了 response 及 connections 時間。底下是針對 Node.js vs Go 語言轉換比較。
↧
ScaleDrone Websocket 平台從 Node.js 轉換到 Golang
↧
在 Docker 偵測 MySQL 或 Postgres 是否啟動
監控 Service 是否存活也是 DevOps 重要的一環,此篇來紀錄在 Docker 內偵測 MySQL 或 Postgres 是否已經啟動。在 Docker 自動測試內,其中一步就是建立 Database 環境,底下為測試步驟:
測試步驟
- 啟動 Database 服務
- 執行 Database Migration
- 關閉 Database 服務
啟動 Database 服務
在 Docker 要啟動 Database 服務相當容易,底下分別為 MySQL 及 Postgres 啟動步驟# Postgres $ docker run --name some-postgres \ -d postgres:latest # MySQL $ docker run --name some-mysql \ -d -e MYSQL_ROOT_PASSWORD=1234 \ mysql:latest
偵測 Database 服務
透過 Docker exec 指令偵測 MySQL 及 Postgres 是否啟動,Postgres 透過pg_isready
指令,Mysql 則是使用 mysqladmin
# Postgres $ docker exec some-postgres pg_isready -h 127.0.0.1 127.0.0.1:5432 - accepting connections # MySQL $ docker exec some-mysql mysqladmin -uroot -p123 ping mysqld is alive # 或者是直接執行單一 SQL 語法 $ docker exec some-mysql mysql -uroot -p123 \ -e "SHOW Databases;"在 Docker 內如果是用
mysqladmin ping
的方式,我發現會抓不到 $?
錯誤代碼,所以還是建議用後者方式,透過執行單一 SQL 方式,在 HAProxy 搭配 Percona XtraDB Cluster 也是透過後者來偵測,詳情可以參考之前寫的『Percona XtraDB Cluster 搭配 HAProxy』。知道如何偵測後,就要寫 While 迴圈每一秒持續偵測。
while ! pg_isready -h postgres; do output "Database service is unavailable - sleeping" sleep 1 done完成上述偵測步驟,就可以正常執行 Databse Migration
Related View
↧
↧
用一行指令加速 npm install
不久之前寫過一篇 提升 npm install 安裝速度,但是發現速度還是沒有變快,在 DevOps 的流程花在
npm install
的時間非常冗長,造成每次測試或 Deploy 都要花大量時間等待,且吃掉很多機器的資源,本篇要提供一個小技巧改善 npm install 安裝時間,其實簡單來說就是 cache 第一次安裝好的 node_modules
目錄,之後每次安裝就拿 cache 目錄來新增或減少 packages 即可。
一行指令
底下一行指令請加入測試流程內,讓 CI Server 專注在測試$ tar xf ../nm_cache.tar && \ npm prune && \ npm install && \ tar cf ../nm_cache.tar node_modules步驟很簡單,先拿上一次備份的
node_modules
,再透過 npm prune
移除不必要的 package,再透過 npm install
安裝新的 package,最後一樣打包給下一次測試使用。這指令非常好用,不管你是不是用 npm@3 都很需要這指令加速 npm install。底下是我隨意拿一個 open source 專案來測試,先假設沒有 cache 機制。
$ rm -rf ~/.npm && rm -rf node_modules && time npm install real 2m7.751s user 1m8.704s sys 0m19.272s如果導入 cache 機制
$ time (tar xf ../nm_cache.tar && npm prune && rm -rf ~/.npm && npm install && tar cf ../nm_cache.tar node_modules) > labs-web@0.0.1 postinstall /Users/mtk10671/git/labs-web > node node_modules/fbjs-scripts/node/check-dev-engines.js package.json real 0m32.370s user 0m19.884s sys 0m13.582s從 2 分 7 秒變成 32 秒,大約提升了 4 倍,大家可以嘗試看看,這招在 Deploy 跟測試非常有感覺。
Related View
↧
感謝老婆 Yisin 這一年來的辛苦
↧
用 Docker 改善團隊合作模式
今年第一次參加 iThome 舉辦的 DevOps Summit 研討會,這次舉辦在台北文創大樓,就是在大巨蛋隔壁,很高興今年第一次投稿就錄取,題目是『用 Dokcer 改善團隊合作模式』,主題偏向如何用 Docker 改善個人或團隊的開發狀況,尤其是在 IC 或系統廠如何導入 Docker。研討會上沒有提到很深入的 Docker 應用,在投影片內強調的是,如何將 Git 及 Docker 帶入團隊內不同角色,包含 QA 及 PM,讓大家在團隊合作上能夠各自獨立,不會互相影響。底下就是我今年的投影片:
最後補上會場圖片
另外大巨蛋真的是沒在動工 XDD
Related View
↧
↧
新的 code coverage 線上服務 codecov.io
代碼覆蓋率 (code coverage) 是開發流程蠻重要的一環,用來評估專案內測試的覆蓋率,也代表了自己寫的程式,至少要測試過一次。在 Github 上面最常用的一套就是 Coveralls 相信大家對於此服務並不陌生,一個好的 Open Source 專案一定會在 Readme 上附上 coveralls badge,證明自己寫的專案都有經過測試,請安心使用。在導入 coveralls 服務到專案內時,安裝步驟有點小複雜,雖然不難,但是還是需要安裝一些 Tool 才能完成,底下用 Golang 為例。
Coveralls.io
Coveralls 會先給一把 Token,你要將 Token 加密到 Travis 設定檔,或者是直接將明碼寫到.travis.yml
檔案內,如果我們要的是前者,就必須在個人電腦裝上 travis
指令
$ gem install travis使用 gem 指令之前,請先把 Ruby 環境安裝好,看到這裡是不是覺得很麻煩了。完成後,透過底下指令將 Token 加密到 config 內
$ travis encrypt COVERALLS_TOKEN=xxxxx--add env.global就可以到
.travis.yml
看到
env: global: secure: jeSgPztK8ytfBEBlZiswBIjXd1dafxxxx還沒結束,你要將 golang coverage report file 送到 Coveralls Server 前,還要安裝 goveralls 工具來完成此任務
install: - export GO15VENDOREXPERIMENT=1 - glide install - go get golang.org/x/tools/cmd/cover - go get github.com/mattn/goveralls上面的最後一行是必須的喔。最後執行測試後才將結果傳到 server
script: - make test - go test -v -covermode=count -coverprofile=coverage.out - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken=$COVERALLS_TOKEN
Codecov.io
這是最近在 Github 其他專案看到的新的服務,Codecov 服務優於 Coveralls 的地方在安裝容易,加上 code coverage 介面比較漂亮,所以目前將新的 open source 專案都換到 Codecov 了,底下先來講安裝方式,安裝方式真的太無腦了,只要先透過 Github 登入到 Codecov,並且將自己的專案加入,就可以看到底下畫面 有看到安裝方式嗎?就只有一行script: - go test -v -covermode=count -coverprofile=coverage.out after_success: - bash <(curl -s https://codecov.io/bash)只要你是 open source 專案,根本不需要 token,Coveralls 會自動分析 golang 編譯出來的 report。在 Dashboard 你會發現這句話
Not required on Travis-CI, CircleCI or AppVeyor for public repositories.只要你是用 Travis 就可以無腦安裝啦。當然也可以自訂選擇 CI Provider。另外如果是 Pull Request,可以發現 Codecov 給的 Report 比 Coveralls 好多了,請直接看此 PR 最後請裝上 Coveralls 提供的瀏覽器外掛,這樣可以直接在 Github 專案原始碼內直接看到 code coverage 數據,請直接看範例 更多 Extension 介紹可以直接看官網影片 就介紹到這邊,大家快去註冊使用吧
Related View
↧
在 Travis 升級 Docker 和 docker-compose 版本
Travis 是在 Github 上常用的整合測試服務,支援了各種程式語言 Golang, PHP, Node.js ..等測試及部署,也同時支援了一些常用 Service,像是 Docker, Redis 或 Database。這次來聊聊在 Travis 如何使用 Docker,在 Travis 內建的 Docker 跟 docker-compose 版本都是非常舊,所以使用預設的 docker-compose 指令常常會出現 (詳細 build log 可以參考這裡)
Error log
會有兩種錯誤訊息,第一種是docker-compose -f docker/docker-compose.yml run golang-build Creating network “docker_default” with the default driver ERROR: 404 page not found make: *** [test] Error 1第二種是
docker-compose -f docker/docker-compose.yml run golang-build Unsupported config option for services service: ‘golang-build’ make: *** [test] Error 1
解法
雖然官方網站有教如何升級 docker-compose,但是光是升級 docker-compose 是沒用的,如果 docker-engine 沒有升級,還是會出現此錯誤訊息,正確解法就是將 docker 也順便升級,打開.travis.yml
檔案,在 before_install
內補上底下 script。
services: - docker env: DOCKER_COMPOSE_VERSION: 1.7.1 before_install: - sudo apt-get -y update - sudo apt-get -y purge docker-engine - sudo apt-get -y install docker-engine - sudo rm /usr/local/bin/docker-compose - curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose - chmod +x docker-compose - sudo mv docker-compose /usr/local/bin請參考完整的 .travis.yml 設定檔。
Related View
↧
在 Jenkins 跑 Golang 測試
本篇會紀錄如何在 Jenkins 測試 Golang 專案,直接拿 go-hello 當作本篇範例。
安裝 Jenkins
請直接參考官網 Wiki 安裝方式,完成後可以發現預設跑在8080
port,搭配 Nginx 設定就可以跑在 80
port。
server { listen 80; server_name your_host_name; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Fix the "It appears that your reverse proxy set up is broken" error. proxy_pass http://127.0.0.1:8081; proxy_read_timeout 90; } }
安裝 Golang Plugin
請先到 Manage Jenkins > Manage Plugins > Available 找到 Go Plugin,安裝後,請到Global Tool Configuration
內把要測試的版本安裝到 Jenkins 內
設定 Jenkins 專案
要跑 golang 測試非常簡單,只需要兩個指令就可以測試$ go get -t -d -v ./... $ go test -v -cover ./...設定完成後,跑測試,會出現底下錯誤訊息
package github.com/gin-gonic/gin: cannot download, $GOPATH not set. For more details see: go help gopath可以發現 jenkins 預設不會將
$GOPATH
設定好,所以必須手動將 $GOPATH
相關目錄設定完成,請不要將 $WORKSPACE
設定成 $GOPATH
,因為 $WORKSPACE
目錄底下包含 src
, pkg
, bin
三大目錄,請將底下 Script 設定到專案內
export GOPATH=$WORKSPACE/gopath export PATH=$GOPATH/bin:$PATH mkdir -p $GOPATH/bin mkdir -p $GOPATH/src/github.com/appleboy/go-hello rsync -az --exclude="gopath" ${WORKSPACE}/ $GOPATH/src/github.com/appleboy/go-hello從上面可以發現,我們手動建立了
gopath
目錄來指定為 $GOPATH
,並且將專案的目錄都設定好後,把 $WORKSPACE
內所有檔案透過 rsync
方式丟到 $GOPATH
內,這樣就可以進行測試了。export
可以用 EnvInject Plugin 取代。
結論
很多人會問為什麼$GOPATH
是指定在 $WORKSPACE/gopath
而不是 $GOROOT/gopath
,如果採用後者的話,這樣多個專案使用不同版本的第三方套件就會出問題,而且共用目錄會造成蠻多額外問題,也無法在測試後完整刪除相關目錄。將 $GOPATH
設定在專案內就可以透過 Workspace Cleanup Plugin 直接清除,讓每次測試環境都是非常乾淨。
Related View
↧
2016 COSCUP 用 Golang 寫 Microservices
今年在 COSCUP 投稿『用 Golang 寫 Microservice』,這場議程最主要是介紹 Golang 入門篇,以及用了哪些 Golang Library 在 Microservices 上,目的希望能多推廣 Golang 語言在 Server 開發上,將來能更多公司導入使用。底下是今年的簡報及大綱:
議程簡介
- Microservices 介紹
- 為什麼用 Microservices
- Golang 簡介及應用
- Golang 測試相關工具
- Docker 整合部署 Golang
問與答
議程最後有人問到 Golang 怎麼處理 Package 版本管理,其實 Golang 有整理一份 Package Management Tools Wiki。最後謝謝 Evan Lin 大大幫忙主持會議。Related View
↧
↧
Drone CI Server 搭配 Atlassian Bitbucket Server (前身 Stash)
目前團隊是使用 Atlassian Bitbucket 搭配 Bamboo,雖然 Bamboo 搭配自家的 Bitbucket (前身是 Stash Server) 整合得相當不錯,但是個人覺得設定上蠻複雜的,所以才想測試看看其他家 CI Service 對團隊學習及設定上更容易。最近找到一套用 Golang 寫的 CI Server 就是 Drone,Drone 線上文件提供了 Github, Gitlab, Gogs, Bitbucket (Stash) 等整合。在整合 Drone 搭配 Bitbucket 時,文件寫得不是很清楚,尤其是在 Bitbucket 建立 Application Link 遇到許多問題,官方文件也沒寫得很清楚,故寫此篇記錄如何將 Drone 服務整合 Bitbucket 伺服器。
建立 Application Link
表單需要注意的地方是Customer Key
跟 Shared Secret
這兩欄位請直接到 Drone 設定檔內找到
DRONE_SECRET: "replace-this-with-your-own-random-secret" DRONE_STASH_CONSUMER_KEY: "AppleBoy46"最下面的
Create Incoming Link
要勾選,完成後按下一步會出現底下畫面
這邊要注意的是我們尚未建立 Public Key,所以請繼續看底下如何建立。
建立 Private Key File
要跟 Bitbucket 的 OAuth 建立連線,則需要 private 跟 public RSA certificate,底下是建立 private certificate$ openssl genrsa -out /etc/bitbucket/key.pem 1024上面會建立一把 private key 存放到
mykey.pem
,下一個指令則是產生 public certificate
$ openssl rsa -in /etc/bitbucket/key.pem -pubout >> /etc/bitbucket/key.pub完成後,請打開
/etc/bitbucket/key.pub
,將內容複製到上述表單內 public key
欄位。另外要將 /etc/bitbucket/key.pem
位置設定在 Drone config 內。
DRONE_STASH_CONSUMER_RSA: "/etc/bitbucket/key.pem"完成後就可以看到底下畫面 看到這畫面算是大功告成了。送了新 PR 給 Drone 官方團隊,今天寫文件才知道之前送的 PR 有錯誤。
參考
Related View
↧
用 Travis 自動上傳 Docker Image 到 Docker Registry
在今年七月寫了一篇『在 Travis 升級 Docker 和 docker-compose 版本』,就在上個月底 Travis 終於將 Docker 預設版本換成 1.12.x 版本,並且將 docker-compose 也一併升級到 1.8.0,這樣就可以不用手動升級了。那這篇會紀錄如何用 Travis 自動編譯 Docker Image 並且上傳到 Docker Hub。Docker Hub 提供兩種方式讓開發者上傳 Image,第一種是透過 Command line 下指令手動上傳,另外一種則是在 Docker Hub 後台指定 Dockerfile 路徑及需要執行編譯的分支,這樣只要 Push commit 到 Github,Docker Hub 就會根據 Dockerfile 來自動編譯 Docker Image。本篇會介紹如何透過 Travis 服務來自動上傳 Dokcer Image,像是 Golang 的部屬方式通常是編譯出 Binary 執行檔後,將此執行檔加入 Image 最後才上傳。
在 Travis 啟動 Docker Service
啟動方式非常簡單,只要加入底下程式碼到.travis.yml
services: - docker
準備 Dockerfile 編譯 Image
我們用 Golang 為例,底下是 Dockerfile 範例FROM alpine:3.4 RUN apk update && \ apk add \ ca-certificates && \ rm -rf /var/cache/apk/* ADD drone-line /bin/ ENTRYPOINT ["/bin/drone-line"]接著透過底下指令編譯出 Dokcer Image
$ docker build --rm -t $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE) .
DEPLOY_ACCOUNT
是 Dokcer hub 帳號,以我的帳號為例就是 appleboy,DEPLOY_IMAGE
則是 Image 名稱。請將這指令寫道 .travis.yml
內的 script
內
script: # 執行測試 - make test # 通過測試後開始編譯 Image - docker build --rm -t $DEPLOY_ACCOUNT/$DEPLOY_IMAGE .最後一道指令就是上傳了
上傳 Image 到 Docker Hub
由於上傳到 Docker Hub,需要登入帳號密碼,而 Travis 提供兩種方式讓開發者設定 Private global value,你不會想把帳號密碼用明碼方式寫在.travis.yml
吧。在早期 Travis 只提供一種方式就是透過 travis
指令來新增,詳細指令可以參考這文件,這邊就不教大家指令了,而另一種方式就是到 Travis 管理頁面直接進到 settings 設定即可
將帳號密碼設定完成後,請在 after_success
加上上傳指令
after_success: - if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_GO_VERSION" == "1.7.1" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"; make docker_deploy tag=latest; fi上面表示只要是
master
分支,測試環境為 Golang 1.7.1 且不是在 Pull Request 狀態就執行登入,並且上傳,其中 make docker_deploy tag=latest
代表意思如下 (我把指令寫在 Makefile 內):
docker tag $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):latest $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):$(tag) docker push $(DEPLOY_ACCOUNT)/$(DEPLOY_IMAGE):$(tag)上面步驟完成,之後只要 commit 到主分支,Travis 就會自動編譯 Image 並且上傳到 Dokcer Hub,蠻方便的。
Related View
↧
在 Travis 實現 Docker Cache
前一篇寫了『用 Travis 自動上傳 Docker Image』,Travis 跑完測試成功後才自動編譯 Docker Image 並且上傳到 Docker Hub。在每次 commit 後,Travis 執行 docker build 時間總是非常長,當然原因很多。如果選用的 Docker base image 非常肥,指令非常多,每次編譯都要重新下載及執行指令,所以執行時間就是這麼長。本篇就是想辦法減少 Travis 編譯 Image 時間,就像把
node_modules
壓縮起來,下次執行測試前先解壓縮再安裝,可以大幅減少 npm install 時間(可以參考之前的『用一行指令加速 npm install』)。這邊我們就需要用到 Travis 的 Cache 功能。
啟動 Travis Cache 快取服務
啟動方式如下:cache: directories: - ${HOME}/docker假設有其他目錄需要 cache,像是 npm 的
node_module
或是 Laravel 的 vendor
,都可以透過此方式設定。
讀取 Docker Cache 快取
在before_install
內透過 docker load 指令讀取 cache 資料
before_install: - if [ -f ${DOCKER_CACHE_FILE} ]; then gunzip -c ${DOCKER_CACHE_FILE} | docker load; fi其中 DOCKER_CACHE_FILE 可以定義在 env 內
env: global: - DOCKER_CACHE_FILE=${HOME}/docker/cache.tar.gz
儲存 Docker Image cache 快取
經過測試及編譯 Image 後,就可以進行 儲存 Docker 快取script: # 進行測試 - make test # 編譯 Image - make docker # 儲存快取 - if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then mkdir -p $(dirname ${DOCKER_CACHE_FILE}); docker save $(docker history -q appleboy/drone-line:latest | grep -v '<missing>') | gzip > ${DOCKER_CACHE_FILE}; fi透過 docker save 指令將 Image 存起來,這樣下次再執行編譯 Image 時,就會先找看看是否有快取。上面設定只有 master branch 才會儲存快取,但是在任何一個 branch 都可以享受到快取的服務喔。
Related View
↧
SSH agent forwarding 教學
SSH agent forwarding 可以讓開發者將 Local 端的 SSH Key Pair 帶到另外一台機器進行傳送,也就是說你不用將 SSH Key 複製到遠端 Server 再進行跳板動作,原本在 AWS 維護多台 EC2 主機,都會固定有一台跳板機,大家都把自己需要登入遠端機器的 SSH Key 複製到跳板機,這做法其實沒有很安全,又需要多下一個指令進行跳板。
個人電腦 —-> EC2 跳板機 —-> EC2 Server大家都會把 Key Pair 存放到跳板機,安全性堪憂,只要這台主機被 Hack,或者是內部員工登入,拿別人的 Key Pair 登入其它主機,不就可以搞破壞?所以此篇教學主要教大家如何設定 SSH agent forwarding,讓憑證只存放在自己電腦,而不需上傳到
EC2 跳板機
。這樣跳板機就真的只是跳板機,不需要存放任何憑證資料,每小時設定清空 Ubuntu User 家目錄,避免內部員工放個人資料或憑證,提升主機安全性。
將 Key Pair 方到清單
透過ssh-add
指令將 Private Key Pair 加入清單
$ ssh-add ~/.ssh/keys/labs.pem透過底下指令可以看到清單列表
$ ssh-add -L這邊注意可以將所有機器的 key pair 都放到
~/.ssh/keys
目錄,並且設定 400
權限
設定 ~/.ssh/config
設定~/.ssh/config
檔案,每個 Host 都加上 ForwardAgent yes
參數
Host aws HostName 10.130.xxx.xxx User ubuntu ServerAliveInterval 60 ForwardAgent yes UseRoaming no IdentityFile ~/.ssh/keys/aws.pem最後執行底下指令就可以直接跳到您要的 EC2 Server
$ ssh -t aws 'ssh example.inc'直接就跳到 EC2 Server,不用再跳板機多下一個 SSH 登入指令,蠻方便又安全。內部 Host Name 可以透過設定 AWS Private Hosted Zones。
Related View
↧
↧
申請 Let’s Encrypt 免費憑證讓網站支援 HTTP2
寫這篇最主要推廣讓網站都支援 HTTPS 加密連線及 HTTP2 協定,對於網站為什麼要支援 HTTP2,可以直接參考 ihower 寫的說明文章,最近在玩 Facebook, Line, Telegram Bot 時,填寫 Webhook URL,都強制要填寫 https:// 開頭,所以更不能忽略 HTTPS 了。,去年底寫了一篇 Let’s Encrypt 開放申請免費 SSL 憑證 推廣 Let’s Encrypt 的貢獻,讓買不起憑證,又想玩看看 HTTP2 的開發者可以用很簡單的方式來安裝及自動更新憑證,而 gslin 大為了推廣 HTTPS 也做了一個網站教學,文章寫得相當清楚,支援 Apache 及 Nginx 設定。
安裝方式
如果主機是使用 Amazone EC2,可以直接用 AWS Certificate Manager,用 AWS 的好處就是只要透過後台介面搭配 ELB 就可以直接設定好 HTTPS 對應到 EC2 主機,壞處就是直接被綁死,將來如果不要使用 AWS,要轉移機器會相當痛苦。所以本篇會紀錄如何用 Nginx 搭配 Let’s Encrypt。為了方便部署機器,我們選用 dehydrated 來設定 Let’s Encrypt,好處就是不用安裝 Python 套件,官方網站提供的安裝方式需要安裝 Python 相關環境。透過 wget 將 dehydrated 安裝到/etc/dehydrated/
底下
$ mkdir -p /etc/dehydrated/ $ wget https://raw.githubusercontent.com/lukas2511/dehydrated/master/dehydrated -O /etc/dehydrated/dehydrated $ chmod 755 /etc/dehydrated/dehydrated
建立設定檔
建立 dehydrated config 設定檔$ echo "WELLKNOWN=/var/www/dehydrated" > /etc/dehydrated/config $ mkdir -p /var/www/dehydratedNginx 設定,先在 80 port 的 Server section 內寫入底下設定:
location /.well-known/acme-challenge/ { alias /var/www/dehydrated/; }可以先丟個檔案到
/var/www/dehydrated/
確定網站可以正常讀取檔案,接著透過 dehydrated 指令產生 SSL 設定檔
$ /etc/dehydrated/dehydrated -c -d fbbot.wu-boy.com執行上述指令會看到底下結果
# INFO: Using main config file /etc/dehydrated/config Processing fbbot.wu-boy.com + Signing domains... + Generating private key... + Generating signing request... + Requesting challenge for fbbot.wu-boy.com... + Responding to challenge for fbbot.wu-boy.com... + Challenge is valid! + Requesting certificate... + Checking certificate... + Done! + Creating fullchain.pem... + Done!最後在設定一次 nginx
server { # don't forget to tell on which port this server listens listen 80; # listen on the www host server_name fbbot.wu-boy.com; # and redirect to the non-www host (declared below) return 301 https://fbbot.wu-boy.com$request_uri; } server { listen 0.0.0.0:443 ssl http2; server_name fbbot.wu-boy.com; location /.well-known/acme-challenge/ { alias /var/www/dehydrated/; } ssl_certificate /etc/dehydrated/certs/fbbot.wu-boy.com//fullchain.pem; ssl_certificate_key /etc/dehydrated/certs/fbbot.wu-boy.com/privkey.pem; location / { proxy_pass http://localhost:8081; } }上面是將 80 port 自動轉到 https,如果下次要重新 renew 的時候才不會又要打開 80 port 一次。
加入 Cron 設定
每天半夜可以自動 renew 一次,請參考 https://letsencrypt.tw/ 最後章節0 0 * * * root sleep $(expr $(printf "\%d" "0x$(hostname | md5sum | cut -c 1-8)") \% 86400); ( /etc/dehydrated/dehydrated -c -d fbbot.wu-boy.com; /usr/sbin/service nginx reload ) > /tmp/dehydrated-fbbot.wu-boy.com.log 2>&1
後記
除了這方法之外,也可以使用 Certbot 來自動更新憑證,但是這方式就是要安裝 Python 環境,不過也不是很難就是了,可以直接參考這篇『NGINX 使用 Let’s Encrypt 免費 SSL 憑證設定 HTTPS 安全加密網頁教學』。結論就是你可以在網路上找到超多種方法來申請 Let’s Encrypt 憑證,就找到自己覺得不錯的方法即可,而我是認為不用安裝 Python 環境的方式最適合部署了。Related View
↧
用 Yarn 取代 Npm 管理 JavaScript 套件版本
新一代戰神 Yarn 終於在昨天出爐了,Yarn 跟 Npm 一樣都是 JavaScript 套件版本管理工具,但是 Npm 令人詬病的是安裝都是非常的慢,快取機制用起來效果也不是很好,所以 Yarn 的出現解決了這些問題,透過 Yarn 安裝過的套件都會在家目錄產生 Cache (目錄在
上面表格將數據整理好,如果要搞 Devops 至少可以省下將近 13 秒的時間,如果是 Local 團隊開發省下的時間更多了。結論就是大家趕快從 npm 轉到 yarn 吧,yarn 出來不到一個禮拜已經超過 1 萬多個 Star 了,看到開發團隊內包含了許多 Google 前端大神,這讓我更放心的轉換到 Yarn。寫完本篇才發現官方也有提供效能比較表。本文提到的數據及檔案都有一併放到 Github Repo
~/.yarn-cache/
),也就是只要安裝過一次,下次砍掉 node_modules
目錄重新安裝都會從 Cache 讀取。Yarn 詳細的功能架構可以參考 Facebook 發表的 Yarn: A new package manager for JavaScript,本篇不會教大家怎麼使用 Yarn,因為指令實在是太容易了,可以參考官方提供的如何從 npm 轉換到 yarn,底下則是來測試比較兩者安裝套件的速度。
前置準備
你可以用任何機器會筆電來做底下測試,或者是直接拿此 Dockerfile 在個人環境先產生乾淨的 Image,Dockerfile 內容很短,也可以從底下複製FROM node:6.7.0 RUN curl -o- -L https://yarnpkg.com/install.sh | bash && \ echo "" >> ~/.bashrc && \ echo 'export PATH="$HOME/.yarn/bin:$PATH"' >> ~/.bashrc CMD /bin/bash請準備好底下版本
- node version: v6.7.0
- npm verison: 3.10.3
- yarn verison: 0.15.1
package.json
或是下載我放在 Github 的 package.json 來做測試。
測試 package 安裝速度
第一階段就是沒有任何 Cache 之下來測試安裝速度$ npm cache clean $ npm install結果: 93.00 秒
$ yarn cache clean $ yarn install結果: 42.80s 第二階段就是保留
node_modules
目錄,在下一次安裝
$ npm install結果: 13.00 秒
$ yarn install結果: 0.16 秒 (注意連 1 秒都不到 XD)
結論
npm | yarn | |
---|---|---|
install without cache | 93000ms | 42800ms |
install with cache | 13000ms | 160ms |
Related View
↧
用 Docker 發送 Line 訊息
今年各家網路公司 (Facebook, Line 和 Telegram…) 分別推出 Bot 服務,看起來 Bot 會是未來趨勢,對 Bot 不是很了解的話,可以參考 Eric ShangKuan 寫了一篇: 關於寫對談機器人 (bot) 的兩三事。本篇會介紹如何透過 Docker 整合 Line Message API,下面所有指令都會跟 Docker 有關,但是程式碼都是用 Golang 撰寫,想說順便在台灣推廣 ^__^。就在今年四月 Line 推出第一版 SDK,但是到了九月,突然收到 Line 的通知,說舊版的不支援了,請大家換到新板 API,最近更動到新版本時,踩到官網 UI 的雷就是原來 Line 有分 Developer 跟一般帳號,這兩種差別就是在於有無
主動 Push Message
功能,後來在 Line-Go-SDK 發問才找到解答。底下會一步一步教大家如何透過 Docker 發送 Line 訊息。
步驟一: 申請 Line Developer 帳號
如果已經有帳戶請略過此步驟。請先到 LINE Business Center,點選Developer Trial
,建立組織及建立帳號,如下圖
完成後,點選 Line Manager,啟動 API
請務必啟動底下設定
- Use webhooks
- Allow Bot to join group chats
- REPLY_MESSAGE
PUSH_MESSAGE
PUSH_MESSAGE
權限,Bot 才可以主動發訊息給使用者
步驟二: 取 Line Token 和 Secret
回到 LINE Business Center 頁面,Tools
底下選 Line Developers
,就可以看到 Channel Secret
及 Channel Access Token
,要取 Token 請點選右邊的 Issue
按鈕就可以顯示了
表單內的 Webhooks URL 是要填寫 https
開頭的 URL,下個步驟會教大家如何透過 Docker 架設 Line Webhook 服務。
步驟三: 用 Docker 啟動 Line Webhook 服務
此步驟是教大家如何取得使用者 ID,前提是使用者必須加 Bot 為好友。要啟動 webhook 服務有兩種方式,一種是透過 docker,另一種則是透過 Golang 方式,我們先來試試看 Docker 方式。下載程式碼
$ git clone https://github.com/appleboy/drone-line.git $ cd drone-line
編譯 Docker Image
進入 example 目錄後,會發現有 server.go 跟 Dockerfile 兩檔案$ docker build -t line example上面的
line
可以自行換掉,換成自己想要的名字,接著啟動編譯好的 Image。
啟動 Webhook 服務
$ docker run --rm \ -e CHANNEL_SECRET=xxxx \ -e CHANNEL_TOKEN=xxxx \ -p 8089:8089 \ line如果不是透過 Docker,請直接執行 Go 指令即可
$ go run server.go
用 ngrok 穿牆
這時候會發現系統聽8089
port,接著透過 ngrok 來做穿牆,並且提供 https 服務
$ ngrok http 8089拿到
https://xxxx.ngrok.io
後,請到 Line Develop Console 填到 Webhook URL 欄位 (請填入: https://xxxx.ngrok.io/callback
),最後透過 QRCODE 加 Bot 為好友,並且發送訊息測試,可以發現在 Console 端會顯示:
2016/11/15 08:04:22 User ID is U77234666b0313021f873b85xxxxxxx這就是您專屬的 User ID,請記錄下來。
步驟四: 用 Docker 主動發送 Line 訊息
透過 drone-line 包好的 Docker Image (appleboy/drone-line)來主動發送訊息,來到這邊,就是假設你已經取得 Line Secret, Token 及使用者 ID,透過下面 Docker 指令docker run --rm \ -e LINE_CHANNEL_SECRET=xxxxxxx \ -e LINE_CHANNEL_TOKEN=xxxxxxx \ -e PLUGIN_TO=xxxxxxx \ -e PLUGIN_MESSAGE=test \ appleboy/drone-line其中
LINE_CHANNEL_SECRET
, LINE_CHANNEL_TOKEN
和 PLUGIN_TO
請填入相對應設定。如果覺得指令太長,也可以把設定包在 .env
檔案內
LINE_CHANNEL_SECRET=xxxxxxx LINE_CHANNEL_TOKEN=xxxxxxx PLUGIN_TO=xxxxxxx PLUGIN_MESSAGE=test請務必將檔案放在執行指令的目錄底下,接著透過底下指令發送訊息
docker run --rm \ -e ENV_FILE=your_env_file_path \ -v $(pwd):$(pwd) \ -w $(pwd) \ appleboy/drone-line
總結
本來 drone-line 是 drone ci server 的 plugin,用來完成測試後,通知相關開發者,當然要整合其他 CI 像是 Jenkins 也是可以的,基本上都包成指令了,只要有 Bash 環境都可以運作。老實說 Line 的開發網站,介面不是很人性化,很多功能都不知道在哪邊,也蠻亂的,另外 Line Developer 也有提供綁定 Server IP 才可以發送訊息,這功能不是很即時性,所以大家盡量不要去用。目前也只有 Line 有提供這功能,應該是要避免 Token 跟 Secret 被偷走。最後要注意的是免費的 Developer 帳號一次只能發五則訊息。超過五則訊息,則會吐出底下錯誤:[messages] Size must be between 1 and 5怎麼發送多個訊息呢?請用
,
來分隔 (不要超過 5 個喔)
docker run --rm \ -e LINE_CHANNEL_SECRET=xxxxxxx \ -e LINE_CHANNEL_TOKEN=xxxxxxx \ -e PLUGIN_TO=xxxxxxx \ -e PLUGIN_MESSAGE=我,愛,你\ appleboy/drone-line
Related View
↧
輕量級 Gofight 支援 Echo 框架測試
Gofight 是一套用 Golang 撰寫的輕量級測試工具,專門測試 Golang Web Framework API,可以參考之前一篇教學: 用 gofight 來測試 golang web API handler,在 Echo 框架發布 v3.0.0 之前,Echo 不支援 golang 標準的
http.Request
及 http.ResponseWriter
,反倒是支援 fasthttp,所以我發了 Issue 希望作者可以支援原生的 http 標準,最後沒有得到回應。就在前幾天 Echo 在 v3.0.0 版本把 fasthttp
拿掉,這樣 Gofight 就可以移除特定函示,改用原生 http。
gofight v1 寫法 (舊式)
舊版 gofight v1 針對 Echo 框架測試寫法func TestEchoPostFormData(t *testing.T) { r := New() r.POST("/form"). SetBody("a=1&b=2"). RunEcho(framework.EchoEngine(), func(r EchoHTTPResponse, rq EchoHTTPRequest) { data := []byte(r.Body.String()) a, _ := jsonparser.GetString(data, "a") b, _ := jsonparser.GetString(data, "b") assert.Equal(t, "1", a) assert.Equal(t, "2", b) assert.Equal(t, http.StatusOK, r.Status()) }) }
gofight v2 寫法 (新式)
新版 gofight v2 針對 Echo 框架測試寫法func TestEchoPut(t *testing.T) { r := New() r.PUT("/update"). SetBody("c=1&d=2"). Run(framework.EchoEngine(), func(r HTTPResponse, rq HTTPRequest) { data := []byte(r.Body.String()) c, _ := jsonparser.GetString(data, "c") d, _ := jsonparser.GetString(data, "d") assert.Equal(t, "1", c) assert.Equal(t, "2", d) assert.Equal(t, http.StatusOK, r.Code) }) }可以看到只要取代底下 func 就可以無痛轉換
RunEcho
=>Run
EchoHTTPResponse
=>HTTPResponse
EchoHTTPRequest
=>HTTPRequest
載入新版方式
下載 Gofight v2
$ go get gopkg.in/appleboy/gofight.v2
載入 Gofight v2
import "gopkg.in/appleboy/gofight.v2"
後記
Gofight 有用 glide 做 vendor 套件控管,但是支援 Echo 框架後,發現測試突然壞了,產生了另外 Issue,如果是使用go get -d -t ./...
安裝方式就沒有問題,之後再找時間解決此問題。
Related View
↧
↧
Linode 推出新的 Datacenter 據點 Tokyo 2
在半年前 Linode 13 歲生日送了一份很大的禮物給大家,就是免費讓大家升級記憶體,這個禮物只限定在非東京據點,對於東京的用戶只能等待,就在今天 Linode 終於宣佈新的服務據點 Tokyo 2,新的東京據點比照[現有的牌價]收費,官方也提供教學讓各地區快速的轉換到東京據點。
新增 Tokyo 2 機器
在升級前的第一個步驟就是建立一台新的機器,區域請選擇 Tokyo 2Clone 到新機器
透過官方教學,進入到舊機器後台,點選 Clone 進入畫面,並且選擇需要轉換的機器,下面的硬碟會一併帶到下一個步驟 接著選擇剛剛新建立的機器,上面會有預估的轉換時間 (通常是假象,會比預估時間長更多) 最後會跳到新機器後台可以看到正在轉換 注意: 完成後請回到 Dashboard 首頁將舊的機器砍掉喔後記
我買的是 Linode 4G (48G 硬碟)方案,最後轉換的時間接近一小時,給大家參考看看 看到 4G 的記憶體真是開心Related View
↧
用 drone-line 架設 Line webhook 及發送訊息
之前寫了一篇教學『用 Docker 發送 Line 訊息』,但是前提是你要先學會 Docker,對於完全沒有 Docker 經驗的初學者來說,學習起來相當不容易,所以我將 drone-line 編譯出 Linux, Mac OS X 或 Windows 都可以執行的 Binary 檔案,方便初學者可以直接下載執行檔,在任何環境都可以運作,請直接參考 v1.4.0 Release 頁面,如果還是想用 Docker 版本的,可以直接參考 Docker Hub 上的 drone-line repo,底下會教大家如何執行 Line webhook service 及發送訊息,尚未申請 Line Developer 帳號,請直接參考前一篇教學
使用執行檔
不用學習 Docker 只需要下載執行檔就可以,支援底下環境- Windows adm64/386
- Linux amd64/386
- Darwin (Mac OS X) amd64/386
下載 drone-line 執行檔
不管是 Windows 64/32 位元的作業系統,都可以直接在 drone-line release 頁面 找到相對應的下載點。下載後,直接在 Windows 執行 cmd 指令,跳出命令提示列視窗,鍵入:$ drone-line-v1.4.0-windows-amd64.exe -h看到底下畫面就代表成功了
架設 Webhook Service
透過 Webhook Service 才可以跟 Line Server 互相溝通,拿到使用者專屬 ID,請直接底下指令就可以架設 Webhook service。$ drone-line-v1.4.0-windows-amd64.exe \ --secret xxxx \ --token xxxx \ webhook其中
--secret
及 --token
請自行替換,預設會跑在 8088
port,如果要換連接埠,請使用 --port
參數
$ drone-line-v1.4.0-windows-amd64.exe \ --port 2001 \ --secret xxxx \ --token xxxx \ webhook
傳送訊息
拿到使用者 ID 就可以透過指令直接發送訊息$ drone-line-v1.4.0-windows-amd64.exe \ --secret xxxx \ --token xxxx \ --to xxxx \ --message "Test Message"其中
--to
是代表使用者 ID,如果要傳給多個人,請用 ,
符號隔開。
使用 Docker
還是可以用 Docker 完成跟執行檔相同的結果,本篇是透過 appleboy/drone-line 映像檔來完成架設 Webhook Service
一行指令完成 webhook service 架設docker run --rm \ -e PLUGIN_CHANNEL_SECRET=xxxxxxx \ -e PLUGIN_CHANNEL_TOKEN=xxxxxxx \ appleboy/drone-line webhook如果要換預設連接埠 (8088) 請加上
PLUGIN_PORT
全域變數
docker run --rm \ -e PLUGIN_CHANNEL_SECRET=xxxxxxx \ -e PLUGIN_CHANNEL_TOKEN=xxxxxxx \ -e PLUGIN_PORT=2001 \ appleboy/drone-line webhook
傳送訊息
一樣很簡單,一行指令搞定docker run --rm \ -e PLUGIN_CHANNEL_SECRET=xxxxxxx \ -e PLUGIN_CHANNEL_TOKEN=xxxxxxx \ -e PLUGIN_TO=xxxxxxx \ -e PLUGIN_MESSAGE=test \ appleboy/drone-line
後記
上個月在線上 docker 讀書會,有教大家如何用 Docker 發送 Line 訊息,影片檔如下,不過本篇主要是提供了各 OS 版本的 Binary 檔案,方便大家直接下載使用,連 Docker 都不用安裝了。 對於執行檔或 Docker 有其他問題,可以直接到 drone-line 開 Issue 給我吧。如果喜歡的話,也可以直接 Star 追蹤。Related View
↧
在 Mac 建立新帳號,並且開通 ssh 權限
為什麼我會需要在 Mac 建立新帳號呢,原因就是最近用 Golang 寫了 SCP 工具,此工具支援 Password 或 SSH Public Key 登入,我又不想拿個人帳號寫在 Testing 檔案內,所以才會想到在 Mac 建立一個帳號好了,本篇就是教大家如何在 Mac 建立新帳號,並且開通 SSH 權限。
建立 Mac 帳號
Mac 不像是其他 Linux 作業系統,可以直接透過一行指令完成建立帳號動作,所以透過 Google 找到了這篇解法dscl . -create /Users/drone-scp dscl . -create /Users/drone-scp UserShell /bin/bash dscl . -create /Users/drone-scp RealName "Joe Admin" dscl . -create /Users/drone-scp UniqueID "510" dscl . -create /Users/drone-scp PrimaryGroupID 20 dscl . -create /Users/drone-scp NFSHomeDirectory /Users/drone-scp dscl . -passwd /Users/drone-scp password dscl . -append /Groups/admin GroupMembership drone-scp上面指令完成後,請切到 Root 下重新開機的指令
$ reboot這時候你會看到右上角多了一個帳號
drone-scp
最後登入 drone-scp
帳號來產生個人目錄底下的相關檔案,這樣用 Command 才可以切到該使用者家目錄 /Users/drone-scp
啟動帳戶 SSH 權限
Mac 預設是不讓外面透過 ssh 方式連線到使用者,所以必須透過管理者開通此權限,請到 System Preferences -> Shareing,將左邊 Sidebar 內的 Remote Login 打開,並且把 drone-scp 帳號放入白名單。測試 SSH
首先產生 SSH Key$ ssh-keygen -f id_rsa -N '' -t rsa複製
id_rsa.pub
到 drone-scp 家目錄
$ cp -r id_rsa.pub /Users/drone-scp/.ssh/authorized_keys透過 ssh 指令測試看看是否可以登入,請注意
id_rsa
權限必須為 400
$ ssh -i id_rsa -l drone-scp localhost有看到成功登入的畫面吧 ^___^
後記
寫完這篇才想到,可以用 Docker 來快速架一個 SSH Server,這邊就不多介紹了,新建 Mac 帳號也是蠻快的。Related View
↧