Docker 記一次 docker-compose 完整實踐(轉)

本文介紹docker-compose實踐時的一些疑問與解決方案, 可能對新手略有幫助, 所以整理成文. 有不妥之處歡迎指摘!前端

Q1: docker-compose 如何安裝?

A1: https://docs.docker.com/compose/install/#install-composejava

Q2: 如何建立一個 mongodb docker-compose?

A2: 參照 https://gist.github.com/wesleybliss/29d4cce863f5964a3eb73c42501d99e4node

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 參數;git

  • 使用volumes掛載數據捲到容器, 等同於 docker run 的 -v 參數; 須要注意的是, 當指定volumes掛載關係後, 須要在docker-compose 文件services同級聲明volumes(注意xtest-data後的":"冒號)github

Q3: version: "3" 是什麼?

A3: version指的是docker-compose的version, 詳見https://docs.docker.com/compose/compose-file/#reference-and-guidelinesweb

Q4: 如何在mongo數據庫自動建立用戶?

A4: 能夠寫一個初始化mongo的shell腳本, 並將該腳本寫入mongo鏡像中, 在初始化時執行該腳本.mongodb

具體操做:docker

  • 建立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

其中幾個文件分別爲:shell

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/

相關文章
相關標籤/搜索