6/22 LineBot and Azure


動機 ¶

就是吃飽太閒

某天因為下雨被困在涼亭而有了這個想法,然後又因為常常忘了倒垃圾

所以就寫個自動提醒倒垃圾和當天天氣的 LineBot

原本是想要用 Email,沒想到 Google 在安全性那個地方把我擋下來

所以就改成 Linebot

過程 ¶

這裡主要有兩個功能

  • 提醒天氣 (利用爬蟲抓取資料)
  • 提醒倒垃圾

因為是利用 line 提供的範本,所以 echo bot 的功能也留著

另外一個留著的原因也是因為容易測試

這裡有一個重點是重要資料要寫成.env檔,然後不要上傳

就是讓他們變成 environment variables,避免重要資訊外洩

這裡可以利用 joho/godotenv 套件來完成

Reference : 用 Go 語言讀取專案內 .env 環境變數

這是要說這支程式有用到哪些 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

先嘗試在 heroku 這個雲端平台發布

其實在 heroku 有不好的經驗,但是這平台最簡單,所以先試試

反正就登錄,然後 deploy,我是連接 github 去 deploy 的

有遇到一個問題就是因為 deploy 之前沒有使用 go module 告訴依賴,所以一直失敗

所以我就把 go module 寫在這個步驟前面

這裡不描述太多因為 heroku 有很多問題,像是 idle 太久會自動停止程式

所以我就改到了 Microsoft Azure 這個 cloud platform

原本以為只要程式碼丟上去執行就好了,但是醒醒吧,孩子,太天真了

這裡要把程式轉換成 Docker image 然後上傳 Docker hub ,再到 Azure 下載執行

這步很重要,build 檔案一定要這樣做

$ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main

這應該是要讓程式可以在對應的環境下執行

第一步,先轉換成 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 上的 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 要在 Configuration -> Application setting 裡面設定


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 的錢花得有點多啊,如果免費期過了應該是不會繼續用了


死人棋開了,真的是一款靠賽遊戲


總之呢,再一個月就開學了,不知道會遇到什麼人,過著怎樣的生活

反正呢,過就是過去,就這樣吧,冷靜一下也是不錯的

一次次的失敗,一次次的學習