本文介紹docker-compose實踐時的一些疑問與解決方案, 可能對新手略有幫助, 因此整理成文. 有不妥之處歡迎指摘!
Q1: docker-compose 如何安裝?
A1: https://docs.docker.com/compose/install/#install-compose
Q2: 如何創建一個 mongodb docker-compose?
A2: 參照 https://gist.github.com/wesleybliss/29d4cce863f5964a3eb73c42501d99e4
version: "3"
services:
mongo:
build: mongo: 3.0
volumes:
- xtest-data:/data/db
ports:
- 27017:27017
command: mongod --smallfiles --logpath=/dev/null # --quiet
volumes:
xtest-data:
-
由於使用了ports參數建立mongodb端口的映射, 因此可以在其他mongo客戶端訪問容器數據庫, 等同於docker run 的
-p
參數; -
使用volumes掛載數據卷到容器, 等同於 docker run 的
-v
參數; 需要注意的是, 當指定volumes掛載關系后, 需要在docker-compose 文件services
同級聲明volumes(注意xtest-data后的":"冒號)
Q3: version: "3" 是什么?
A3: version指的是docker-compose的version, 詳見https://docs.docker.com/compose/compose-file/#reference-and-guidelines
Q4: 如何在mongo數據庫自動創建用戶?
A4: 可以寫一個初始化mongo的shell腳本, 並將該腳本寫入mongo鏡像中, 在初始化時執行該腳本.
具體操作:
- 創建mongo目錄, 並在該目錄創建Dockerfile-mongo
FROM mongo:3.0
COPY init_mongo.sh init_mongo.sh
COPY mongodb.conf mongodb.conf
COPY mongo-fork.conf mongo-fork.conf
COPY start_mongo.sh start_mongo.sh
CMD ["./start_mongo.sh"]
EXPOSE 27017
其中幾個文件分別為:
mongodb.conf: mongodb配置文件, 前台運行
mongo-fork.conf: mongodb配置文件, 后台運行
init_mongo.sh: 調用mongo-fork.conf, 后台啟動mongod; 連接並創建mongodb用戶
start_mongo.sh: 調用mongodb.conf, 前台啟動mongod
- 創建一個初始化mongodb的docker-compose.yml
version: "3"
services:
mongo:
build:
context: mongo
dockerfile: Dockerfile-mongo
volumes:
- xtest-data:/data/db
command: ./init_mongo.sh
volumes:
xtest-data:
build下, context表示路徑, dockerfile表示Dockerfile文件名
- 啟動該docker-compose.yml即可調用容器內的初始化腳本, 完成創建用戶.
Q5: 其他容器如何連接mongodb?
A5: 要考慮的幾個問題: 一是host, 二是port;
由於port可以通過ports映射到宿主機, 所以port容易解決. 考慮到安全問題, 只將端口開放給同一個docker-compose的其他容器訪問, 因此用 expose
參數開放 27017
端口;
參考https://docs.docker.com/compose/compose-file/#links, 其他容器使用links
可以將mongo容器的ip記錄到該容器中, 再通過連接 mongo:27017
可以訪問數據庫.
version: "3"
services:
backend:
build:
context: backend
dockerfile: Dockerfile-backend
ports:
- "8099:8099"
- "8009:8009"
links:
- mongo
depends_on:
- mongo
mongo:
build:
context: mongo
dockerfile: Dockerfile-mongo
volumes:
- xtest-data:/data/db
expose:
- "27017"
# uncommand to able host visit mongo
#ports:
# - "27017:27017"
command: ./start_mongo.sh
volumes:
xtest-data:
通過depends_on
來標記依賴關系, 當mongo
服務啟動完成后, 才會啟動backend
服務;
由於后端代碼只考慮到mongodb與后端服務部署在同一台宿主機情況下, mongo的host始終為127.0.0.1
, 因此需要修改后端代碼, 判斷為容器時host=mongo
, 不為容器時host=127.0.0.1
.
Q6: 如何在Python代碼中判斷當前環境是否為容器?
A6: 一個簡單的方法是為該容器添加一個環境變量, 在Python代碼中判斷有該變量時為容器, 沒有時為普通環境.
在后端鏡像的Dockerfile中添加:
ENV DOCKER 1
在Python代碼中添加:
try:
docker_flag = os.environ.get('DOCKER', "")
if docker_flag == '1':
mongo_host = 'mongo'
print('Run in docker!')
else:
mongo_host = '127.0.0.1'
except:
print("Unexpected error:", sys.exc_info()[0])
raise
以上完成對mongo host的設置切換.
Q7: 如何分離前后端, 使得前端代碼修改時無需將所有環境都重新構建?
A7: 單獨創建一個前端鏡像, 掛載一個前端數據卷到該容器中進行編譯, 編譯完成后, 在啟動后端服務時直接掛載前端數據卷即可, 無需再啟動該鏡像. 即: 該前端鏡像只是用於編譯前端文件!
version: "3"
services:
node:
build:
context: node
dockerfile: Dockerfile-node
volumes:
- xtest-front:/www/xtest-web/dist
volumes:
xtest-front:
下載源碼與編譯的過程在Dockerfile中, docker-compose的工作主要是掛載xtest-front數據卷到容器中, 使得編譯后的前端文件能夠持久化到該數據卷中用於與后端交互.
總結
以上是在將 x-utest 系統 Docker 化過程中的經驗收獲, 完整的項目在 https://github.com/x-utest/xtest-docker-compose , 歡迎學習, 也歡迎使用 x-utest 測試系統並提出意見與建議!
關於 x-utest
x-utest相關用法見: [免費 / 開源 / 好用] x-utest 測試開發平台
官方文檔: http://xtest.readthedocs.io/zh/latest/
參考
[1] Compose file version 3 reference, https://docs.docker.com/compose/compose-file/
[2] Docker Compose 項目, https://yeasy.gitbooks.io/docker_practice/content/compose/