動機 ¶
就是吃飽太閒
某天因為下雨被困在涼亭而有了這個想法,然後又因為常常忘了倒垃圾
所以就寫個自動提醒倒垃圾和當天天氣的 LineBot
原本是想要用 Email,沒想到 Google 在安全性那個地方把我擋下來
所以就改成 Linebot
過程 ¶
1. 先寫個簡單的 LineBotApp ¶
這裡主要有兩個功能
- 提醒天氣 (利用爬蟲抓取資料)
- 提醒倒垃圾
因為是利用 line 提供的範本,所以 echo bot 的功能也留著
另外一個留著的原因也是因為容易測試
這裡有一個重點是重要資料要寫成.env檔,然後不要上傳
就是讓他們變成 environment variables,避免重要資訊外洩
這裡可以利用 joho/godotenv 套件來完成
Reference : 用 Go 語言讀取專案內 .env 環境變數
2. go module ¶
這是要說這支程式有用到哪些 package
首先要啟動 GO111MODULE 變數,預設為 auto
$ export GO111MODULE=on
然後初始化專案
$ go mod init github.com/kl23711579/project
然後 project 裡面會出現 go.mod 檔案
等到之後要 build 時就會自動下載了
下載完會出現 go.sum 檔案
Reference : Go 語言 1.11 版本推出 go module
3. Deploy in heroku ¶
先嘗試在 heroku 這個雲端平台發布
其實在 heroku 有不好的經驗,但是這平台最簡單,所以先試試
反正就登錄,然後 deploy,我是連接 github 去 deploy 的
有遇到一個問題就是因為 deploy 之前沒有使用 go module 告訴依賴,所以一直失敗
所以我就把 go module 寫在這個步驟前面
這裡不描述太多因為 heroku 有很多問題,像是 idle 太久會自動停止程式
所以我就改到了 Microsoft Azure 這個 cloud platform
4. Deploy in Azure ¶
原本以為只要程式碼丟上去執行就好了,但是醒醒吧,孩子,太天真了
這裡要把程式轉換成 Docker image 然後上傳 Docker hub ,再到 Azure 下載執行
Build ¶
這步很重要,build 檔案一定要這樣做
$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main
這應該是要讓程式可以在對應的環境下執行
Docker ¶
第一步,先轉換成 docker image,所以要寫 Dockerfile
因為普通的 docker image 的 size 太大了,所以選擇了最小化的寫法
FROM scratch
FROM centurylink/ca-certs
ADD main /
EXPOSE 8090
# COPY time file
COPY zoneinfo.zip /usr/local/go/lib/time/
ENTRYPOINT ["/main"]
scratch 是一個特殊的 docker image,裡面是 empty 的
centurylink/ca-certs 是認證,如果沒有這個,等等和 line 交換資料會出錯
ADD main / 把 main(執行檔) 複製到 / 底下
EXPOSE 8090 把 port 8090 暴露出來接收封包
COPY zoneinfo.zip /usr/local/go/lib/time/ 因為有設定時區,所以要把需要的 lib 複製過去不然會出現下面的錯誤
open /usr/local/go/lib/time/zoneinfo.zip: no such file or directory
ENTRYPOINT ["/main"] 執行程式
Reference1 : 用 Docker Multi-Stage 編譯出 Go 語言最小 Image
Reference2 : Building Minimal Docker Comtainers for Go Applications
Reference3 : Dockerfile 指令教學,含範例解說
Azure ¶
再來照著教學的指令一個一個打就行了,指令是在 azure 上的 command 打
az group create --name AzureGoKL --location "Australia East"
Firstly, create a resource group for application, this group can contain all resources
az appservice plan create --name LineBot --resource-group AzureGoKL --sku S1 --is-linux
Secondly, create a Linux-base app service plan name LineBot, it will use a Linux worker to host the Docker app
az webapp create --resource-group AzureGoKL --plan LineBot --name LineBotAppm --deployment-container-image-name kl23711579/linebot:latest
Finally, create a Docker-based application in Azure, the image name in docker hub is kl23711579/linebot
這樣就結束了
自動更新 ¶
設定自動更新,也就是當 docker hub 上的 image 更新時,這裡也會同步更新
Container setting -> docker hub -> Continous Deployment -> on
然後把 webhook URL 複製到 docker hub 的 repository 的 Webhooks 裡
Environment variables ¶
Environment variables 要在 Configuration -> Application setting 裡面設定
Reference ¶
Reference1 : Step by step guide to deploy Golang Application on Azure Web App
Reference2 : Running Go in Azure with Container Instances
Reference3 : Set environment variables in container instances
Reference4 : 在 Azure App Service 中執行自訂的 Linux 容器
Reference5 : Golang生产环境中time包的zonefile.zip问题
最近真的是太閒了,所以就搞了一個東西
也沒有多麻煩,只是有一堆不熟悉的東西,反正照著做就對了
不過 Azure 的錢花得有點多啊,如果免費期過了應該是不會繼續用了
死人棋開了,真的是一款靠賽遊戲
總之呢,再一個月就開學了,不知道會遇到什麼人,過著怎樣的生活
反正呢,過就是過去,就這樣吧,冷靜一下也是不錯的
一次次的失敗,一次次的學習