這是一篇筆記文,我的文筆很爛,此外我也剛開始接觸Docker,這不是教學而是有點像是踩雷心得,請加減看看,有問題歡迎指教XD
前情提要
我們公司使用CircleCI 作為CI的工具,基本上,CircleCI的使用相當簡單
綁定Github account 到CircleCI → Enable Repository in CircleCI → 撰寫CircleCI config YAML 檔 → 推到Github 上面
理論上他就會針對config裡面的步驟進行一步一步的測試和部署,關於config的撰寫,circleci提供一些 範例 ,這邊就不贅述了。
CircleCI在他們的伺服器上使用Docker container來進行測試,一旦把想要測試和部署的專案推上Github以後,他會觸發一個webhook讓CircleCI開啟一個container進行乾淨的測試和部署。
這次遇到的問題是,如果我今天想要測試一個API app,整合測試的部分一定有可能會使用到其他的服務,例如MySQL、Redis等等,這個就會有一點小小的麻煩了。
一開始我找到了CircleCI的文件,關於不同服務的整合測試,CircleCI有提供官方的 解決方案
但是如果我就是想要用Docker Compose進行測試怎麼辦?(很任性XD) 因為這樣就能直接把在Local端的測試環境直接搬上CI環境,也不用搞一堆其他有的沒的…?
總之,本篇文章主要會以在CircleCI docker環境內再創建另外一個Docker-compose的方法為主,也就是一個container裡面再有container的概念
Talk is Cheap, show me the code ?!
這邊就不囉唆,直接上circleci 的yaml config
以及我們要執行測試的docker compose file 其實就是一個很單純的 api 測試,執行測試的時候需要用到Celery worker,而Celery需要連到Redis & MySQL
docker compose yaml file如下
好像很簡單,對吧?
但是人生沒那麼容易的,如果你就這樣單純的執行下去 你很有可能會遇到一個問題…
django.db.utils.InterfaceError: (2003, "2003: Can't connect to MySQL server on 'db:3306' (111 Connection refused)", None)
M
什麼?!!
竟然連不到DB? 在本機端測試明明都沒問題啊….
問題分析
根據CircleCI提供的錯誤log,分析可能是因為MySQL server壓根沒有被執行起來 基本上docker-compose 如果加上 depend_on
基本上可以指定container執行的順序 例如:
結果?
很不幸的還是一樣的錯誤…
在上述的yaml 可以看到如果在api加上了depens_on,確實可以指定api會在redis 以及 MySQL後 被執行
不過請注意喔,是被執行,並不代表是可以被連線或是服務已經ready,可以參考這篇 文章
解決方案
根據文章的的建議,我們應該可以設定一個小小的檢查器,如果該服務還沒有被確定啟動,就不會執行,讓他一直等,等到dependencies 都確定可以被連線以後,才會執行下一步
這邊我們用的小工具叫做 wait-for-it
基本上就是一個pure bash script,可以用來block住你的程式碼,等到需要等待的資料庫或是其他服務真的 ready 後才會執行
使用範例如下
./wait-for-it.sh db:3306 -- echo "db is up"
也由於他是純bash寫成的,你不用安裝任何的dependencies,直接把那隻bash script丟進repo或是在circleci build的時候直接下載也可
所以改寫後的docker compose會像這樣
可以注意到在celery command的部分,我們加上了wait-for-it的指令,你就會在circleci的log上面發現,他真的有在等待
wait-for-it.sh: waiting 15 seconds for db:3307
然後你的circleci就成功了!!!!!!!!!! :)
結語
當然,我還是認為在circleci的docker container裡面再起一個docker-compose不是一個很好的idea,因為目前我們還是遇到了circleci build time非常久的問題,但是如果你發現circleci提供的 多個conatinaer作法 不合你的胃口,或許你也可以嘗試看看本篇的做法唷。有問題以及指正歡迎在下方留言,謝謝。
Originally published at https://cftang0827.github.io on December 9, 2019.