Deploy Microsoft Bot to Azure Using Docker Container

示範如何使用Docker Container打包Python版Microsoft Bot並部署到Azure

Castle Cheng
17 min readFeb 24, 2020

Microsoft Bot Framework讓Bot的開發變得非常簡單,複雜的對話流程可以用多個Dialog架構解決,連結現在市面上多種通訊軟體也非常輕鬆,因為Framework底層都已經幫你做好了~ 官方GitHub還提供了非常多範例可以參考,每個範例內都詳細介紹了Bot Framework不同的功能。

直接到Azure Portal開啟一個Bot Service(Web App Bot)是大家經常使用的方法,可以選擇不同的語言以及官方已經預先建置好的Bot程式碼模板,還可將source code下載進行修改,完成後再部署到Azure上。

Ok, 以上是一個非常完美的Microsoft Bot開發部署流程。

但是!世界總是有例外。
如果我不想使用Azure Bot Service給我的模板呢?
如果我的Bot是從官方GitHub載下來的Sample Code呢?
如果Azure沒有提供Python Bot 模板呢? (2020/03還沒有提供)

只要不是從官方的模板開始修改,大部分的開發者在部署Bot的時候都會遇到困難。我也經歷過這段撞牆期,希望這份文件可以拯救更多人。

本文將會使用示範如何將一個Python Bot專案打包成Docker image並且部署到Azure Web App作為運算主機,串聯Bot Channels Registration作為管理平台,中間使用Azure Active Directory進行金鑰認證確保不會有外人隨意存取你的Bot服務。

未來開發人員可以依據專案的需求使用不同語言,只要使用Docker正確地將程式打包成image就可以使用本文的方法部署到Azure Web App甚至其他雲端平台,透過Docker部署的優點是可以克服大部分程式執行環境的問題,確保專案再不同的雲端平台間遷移或擴張時不會受到影響。

本地端使用Docker打包 Python專案

事前準備:
1. 電腦具有Docker執行環境
2. Git
3. Python 3.7
4. Python虛擬環境 [建議]

  1. 從GitHub 下載Sample Code:
$ git clone https://github.com/microsoft/BotBuilder-Samples.git

進入 botbuilder-samples\samples\python資料夾,裡面有非常多Python範例,本文以 " 02.echo-bot "為例

2. 開啟終端機,切換目錄到 botbuilder-samples\samples\python\02.echo-bot資料夾中,在一個乾淨的Python環境中(建議啟動虛擬環境)確認這個專案可以用Python正常執行。

$ pip install -r requirements.txt
$ python app.py

3. 下載Bot Framework Emulator,並且透過Emulator與Bot溝通,確認功能正常:

透過Emulator與Bot溝通,確認功能正常

4. [重要!] 開啟 02.echo-bot/app.py 修改以下段落,將原本的”localhost”改成"0.0.0.0",因為在Docker Container中,設定成localhost會讓Bot無法從容器外直接呼叫:

if __name__ == "__main__":    try:
web.run_app(APP, host="0.0.0.0", port=CONFIG.PORT)
except Exception as error: raise error

5. 在 BotBuilder-Samples/samples/python/ 02.echo-bot目錄底下新增一個檔案命名為”Dockerfile”(無附檔名),輸入內容如下:

FROM python:3.7WORKDIR /appCOPY requirements.txt /appRUN pip install -r requirements.txtCOPY . /appEXPOSE 3978CMD [ "python", "app.py"]

這是一個標準的Dockerfile,翻譯出來的流程就是從網路上取得別人已經幫你做好的Python3.7 base image當作基底,再把我們剛剛寫好的Bot程式碼放進去並且使用pip安裝所需要的套件,最後在Container啟動時執行python指令來啟動app.py這個檔案。

6. 在同個目錄底下再新增一個檔案,命名為".dockerignore",輸入內容如下:

.git
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env

如同.gitignore一樣,這個檔案是告訴Docker在建置Docker image的時候要忽略那些檔案,這樣可以降低Docker Image的檔案大小

7. 下載Docker並且啟動Linux Containers模式,開啟終端機,切換目錄到BotBuilder-Samples/samples/python/02.echo-bot 並且輸入以下指令開始建置Docker Image (注意指令最後面有一個 "點" ):

$ docker build -t python-docker-bot . 

這個指令會啟動Docker,並且依照我們剛剛寫的Dockerfile內容建置一個Docker Image名叫 python-docker-bot,這個過程就像你在命令一位廚師依照食譜將料理做出來一樣~
更多Docker基本操作可以參考Docker官方文件:
https://docs.docker.com/docker-for-windows/#docker-settings-dialog

8. Docker Image建置成功之後,就可以輸入以下指令來啟動看看囉(啟動之前請先確定剛剛的Python程式已經關閉,避免port衝突):

$ docker run --rm -it -p 3978:3978 python-docker-bot

這個指令包含許多參數,翻譯出來就是說: 「啟動一個Docker Container,使用的Docker Image是python-docker-bot,將他的輸出導向至我目前使用的終端機,用本機的3978 port對應到Container裡面的3978 port,當這個Container暫停執行後就將他移除」

9. 一樣開啟Bot Framework Emulator來與剛剛建置在Docker Container裡面的Bot打聲招呼吧:

與剛剛建置在Docker Container裡面的Bot打聲招呼

到目前為止就代表這個Bot的Docker Image已經建置完成了!
接下來我們將會把它部署到Microsoft Azure的App Service(Web App)平台上,再結合Azure Bot Service 讓Bot有更多功能~

將Docker Image上傳到Docker Hub

事前準備:
1. 一個可以正常運行在Container裡的Bot
2. 一個Docker Hub帳號

  1. 開啟瀏覽器,前往Docker Hub,登入後新增一個Public的repo,準備放置剛剛建立的Docker image:
記下粉紅色畫線的部分,稍後指令要輸入這一段

本文示範是使用Public的repository,如果有特殊需求要設成Private也可以,但是後續建置Azure Web App的設定就需要再輸入密碼才能建置。

2. 使用$ docker tag指令更改先前運行Bot的Docker image的名稱。
本地端的Docker image name要跟Docker Hub的repository/name相同才能推上Docker Hub,指令規則如下:

$ docker tag <原本Docker Bot image名稱> <你自己DockerHub的ID>/<你建立的repo名稱>

可以先使用$ docker images指令先列出所有的images名稱,找到原本的Image在輸入到指令中。

若依照文章上半部的例子,指令就應該輸入:

$ docker tag python-docker-bot weijuncheng/python-docker-bot

那是我的Docker Hub ID作為示範,請務必一定要改成你自己的Docker Hub ID跟你自己的repository名稱,如同上一張圖粉紅色畫線部分 !!!不然一定會推不上去~

3. 將剛剛建立的Docker image推到Docker Hub。
開啟終端機,先列出所有的docker images看看剛剛是否有更名成功:

$ docker images

檢查剛剛重新命名的Docker image有沒有出在列表裡面,以及這個名稱有沒有與自己的Docker Hub名稱完全一致

檢查剛剛重新命名的Docker image有沒有出在列表裡面

如果有,代表你可以準備將它push到Docker Hub存放了。
輸入以下指令先在終端機登入Docker Hub:

$ docker login

輸入完帳號密碼之後就可以開始Push囉:

$ docker push <你自己DockerHub的ID>/<你建立的repo名稱>

Push的過程會需要一段時間。完成之後你可以到自己的Docker Hub上去看看是不是成功了。

執行 docker push指令的畫面
Docker Hub顯示有image了,Docker Push成功!

記下你這個Docker Hub repository名稱,稍後需要填入到Azure設定中。

如果想了解更多,可以參考另一篇文章,有非常詳盡的說明以及示範,教你如何Push Docker Image: 【iThome- 把 Docker Image Push 到 Docker Hub

部署到Microsoft Azure

事前準備:
1. 一個具備有效訂閱的Microsoft Azure帳號
2. 了解Microsoft Azure基本操作[建議]

  1. 在Microsoft Azure上建立一個Web App。
    (1)開啟瀏覽器前往Microsoft Azure Portal
    (2)點選【新增資源】(或create a resource)搜尋 "Web App",點選【Create】:
建立一個Web App

2. 輸入建立Web App所需要的設定。
(1)Resource Group:建立一個新的資源群組。
(2)Name:為你的Web App取一個望文生義的名稱~
(3)Publish:選擇Docker Container部署。
(4)Operating System:作業系統建議選擇Linux。
(5)Sku and size:可以依專案需求選擇的運算規格。
(6)都完成之後,點選【Next: Docker>】進入下一步

要運行Docker Container的Web App運算規格Size至少需要選擇B1或以上

輸入完成後,點選【Next: Docker>】進入下一步

補充:" Resource group "就像是Azure雲端專案的資料夾,因為每個專案都會由許多服務組合起來,建議每個專案開一個Resource group,方便管理。

3. 輸入你的Docker Hub repository名稱,讓Azure自動去下載並部署。
(1) Options:選取 【Single Container】
(2) Image Source:選擇【Docker Hub】
(2) Access Type:選擇【Public】 (如果是不公開的存放庫則選擇Private,並輸入帳號密碼)
(3) Image and tag:要輸入你自己的Docker Hub repository名稱
(4) 輸入完成之後點選【Review + create】確認設定資料是否正確

輸入完成之後點選【Review + create】確認設定資料是否正確

Azure會自動幫你檢查命名規則、資源創建是否符合規定,若不符合規定,會以紅點標示出來

4. 若沒有出現錯誤訊息表示所有設定都正常,點選【Create】開始佈署。

若沒有出現錯誤訊息,表示所有設定都正常,可以點選【Create】開始佈署

5. 佈署完成就可以點選【Go to resource】前往Web App的主頁囉~

找到頁面中的【URL】項目,那就是這個Web App的Endpoint,請先將網址複製下來(粉紅色框框處),在下一個階段需要填入Azure設定頁面。

到目前為止你已經成功建立一個Web App服務了,代表你的Code已經正常的在雲端上執行了,但是還需要幫這個Bot註冊一份資料,才能夠將它快速串聯到各大通訊軟體平台。

Bot Channels Registration連結

6. 前往Azure Portal首頁,新增一個資源【Bot Channels Registration】。

7. 填入Bot Channels Registration所需要的設定。
(1) Bot handle:幫這個App取個名稱。
(2) Resource group:選取與剛剛建立Web App相同的Resource group。
(3) Pricing tier:實驗階段選取【F0】 等級即可。
(4) Messaging endpoint:填入上一階段建立Web App最後複製下來的URL並且在最後加上 "/api/messages ",規則就跟本地端Bot Emulator需要輸入的Endpoint一樣
(5) 輸入完成之後就可以點選【Create】建立資源

8. 佈署完成之後點選【Go to resource】前往Bot Channels Registration主頁

OK,以上非常複雜的設定完成之後,代表你已經建立好一個Bot的管理平台並且與後端的Web App運算主機做連結,但Azure平台為了確保你的Bot更安全,會搭配Azure Active Directory做安全金鑰認證。接下來只要完成最後一關「認證」就可以開始與Bot溝通了。

9. 點選Bot Channels Registration左邊選單的【Settings】,進入設定頁面。

[重要] 複製下方的Microsoft App ID暫時貼到記事本或便利貼上,因為稍後設定會使用到。

複製完後,再點選一旁的【(Manage)】,進入金鑰管理頁面。

10. 進入頁面之後點選【+New client secret】為你的Bot建立一組金鑰。

11. 輸入這組金鑰的相關設定。
(1) Description:輸入簡單的敘述說明這組金鑰的用處,以便日後系統維護。
(2) Expires:依照你的專案需求選擇金鑰的期限

12. [重要] 建立之後請務必馬上將產生出來金鑰的Value複製下來,因為安全考量,離開這個頁面之後Azure就會鎖定這把金鑰的值,也就不能複製Value了喔!
請盡快按下右邊的複製按鈕,並將它暫時貼到記事本或是便利貼上,稍後會需要使用到。

依照目前的流程,我們已經取得一組Microsoft App ID 以及金鑰了。稍後我們需要將這組帳號、密碼輸入到先前建立的Web App設定中,作為環境參數。

13. 點選左上角【Home】回到自己的Azure Portal主頁。點選剛剛建立的Web App進入資源主頁。

14. 點選左邊的【Configuration】進入Web App的設定頁面。

點選左邊的【Configuration】

15. 點選【+New application setting】建立MicrosoftAppId
(1) Name:輸入"MicrosoftAppId"
(2) Value:輸入剛剛第9.點所提到的Microsoft App ID

點選【+New application setting】新增項目
輸入剛剛第10.點所提到的Microsoft App ID

16. 再點選【+New application setting】建立MicrosoftAppPassword
(1) Name:輸入"MicrosoftAppPassword"
(2) Value:輸入第12.點複製下來的金鑰Value

17. 兩個項目都輸入完成之後點選上方的【Save】儲存Web App的設定,Web App將會重新啟動以載入新的設定檔。

18. 現在可以回到Bot Channels Registration,點選左邊選單的【Test in Web Chat】開始與Bot對話囉!

結語:

恭喜各位完成非常複雜的架構,如此一來所有的Bot資源都已經雲端上正常運行了,本文使用Bot Channels Registration是為了避免直接創建Azure Bot Service時系統會預設幫你建立一個Web App作為運算主機。但如果讀者本身已經有建立過Azure Bot Service,其實也可以直接使用Docker Container建立一個Web App,再將原本Bot Service中設定的Messaging Endpoint改成新的建立的Web App URL,再將原本預設建立的Web App中MicrosoftAppId以及MicrosoftAppPassword複製到新的Web App Configuration當中,便可以成功使用。

後續:

使用Bot Channels Registration的好處是可以與各大通訊軟體串聯,在Azure上稱之為「通道」(Channel),甚至可以在網頁上直接使用JavaScript與Bot溝通,這些方法將會在後續文章陸續新增,敬請期待。

--

--

Responses (1)