Compose 是 docker 提供的一個命令行工具,用來定義和運行由多個容器組成的應用。
使用 compose,我們可以通過 YAML 文件聲明式的定義應用程序的各個服務,並由單個命令完成應用的創建和啟動。
Compose 的使用方式非常簡單,基本上就是下面的三板斧:
- 定義 Dockerfile
- 定義 docker-compose.yml
- 運行 docker-compose up
其實 compose 提供的命令可以管理應用的整個生命周期:
- Start, stop, rebuild services
- 查看運行中 service 的狀態
- 輸出運行中 service 的日志
- 在 service 中執行一次性的命令
本文我們通過一個簡單的 demo 來介紹 Docker Compose 的基本用法。說明:本文的演示環境為 ubuntu 16.04。本文的演示代碼可以從 github 上下載。
安裝 Docker Compose
安裝 Docker Compose 前請先在本地安裝 Docker。
Docker Compose 的安裝十分簡單,在 ubuntu 中直接把可執行文件下載到本地就可以了。
$ sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose
其中 1.22.0 是最新的版本。當然 Docker Compose 是個開源項目,你可以選擇安裝不同的版本,或者是自行編譯。下圖為筆者安裝之后顯示的版本信息:
注意,默認的安裝並不包括命令補全功能,也就是說像 docker-compose restart 這樣的命令,你輸入 docker-compose re 后按 tab 鍵是無法自動補全的。想要這個功能還需要額外的安裝,以 Bash 為例,執行下面的命令:
$ sudo curl -L https://raw.githubusercontent.com/docker/compose/1.22.0/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
然后重新登錄 Bash,就可以通過 tab 鍵自動補全命令了!
創建演示 demo
下面的示例來自 docker 官網,就是一個簡單的 Flask 網頁應用,后端使用 redis 存儲數據,其 web server 的代碼如下(可以從這里下載到本文中的代碼):
import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route('/') def hello(): count = get_hit_count() return 'Hello World! I have been seen {} times.\n'.format(count) if __name__ == "__main__": app.run(host="0.0.0.0", debug=True)
代碼非常簡單,就是對請求計數並顯示給用戶。為了增加健壯性,在訪問 redis 時做了一點處理:嘗試訪問 5 次再報錯。把上面的代碼保存到文件 app.py 中。
要運行上面的代碼,需要在環境中安裝 flask 和 redis 包。創建 requirements.txt 文件,編輯其內容為:
flask
redis
創建一個保存項目文件的目錄,比如 composecounter,把 app.py 和 requirements.txt 文件都放進去。
創建 Dockerfile 文件
接下來我們需要把上面的應用打包到容器鏡像中。在 composecounter 目錄下創建 Dockerfile 文件:
FROM python:3.4-alpine ADD . /code WORKDIR /code RUN pip install -r requirements.txt CMD ["python", "app.py"]
上面代碼的含義為:
- 使用 python:3.4-alpine 作為基礎鏡像
- 把當前目錄添加到鏡像中的 /code 目錄
- 設置容器中的工作目錄為 /code
- 安裝 requirements.txt 文件中指定的依賴包
- 把容器啟動時的默認命令設置為 python app.py
創建 compose 配置文件
終於來到本文的重點了!我們需要創建 Docker Compose 的配置文件來定義我們的應用。
YAML 是一個可讀性高,用來表達數據序列的格式。Docker Compose 使用 YAML 格式的文件作為配置文件。
在 composecounter 目錄中創建 docker-compose.yml 文件,其內容如下:
version: '3' services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
第一行的 version: '3' 表示當前的配置文件使用的語法版本。
services 中的內容指明該應用一共定義了多少個服務(容器鏡像)。在運行時,一個服務是指從該鏡像啟動的一個或多個容器。
在我們的示例中一共需要兩個容器鏡像。web 服務由我們自己通過 build . 命令構建,映射的端口是 flask web server 默認的 5000 端口。
redis 服務則直接使用官方的鏡像。
構建並運行示例程序
在 composecounter 目錄下執行命令:
$ docker-compose up
跳過那些繁瑣的輸出,我們直接訪問本機的 5000 端口:
一個 web 應用程序運行起來了,並且輸出了我們訪問服務器端的次數,看起來還不錯!
如果要讓容器安靜的運行在后台,加上 -d 選項就可以了:
$ docker-compose up -d
背后的事情
分析 docker-compose up 命令的輸出可以看清事情的真相,但是日志過於繁瑣,我們只說重點:
- 創建名稱為 composecounter_default 的網絡
- 使用 Dockerfile 構建 composecounter_web 鏡像
- 創建容器 composecounter_redis_1 和 composecounter_web_1 並加入相同的網絡
如果你手動去執行這些操作還是挺很繁瑣的,現在一個命令就搞定了,還可以把相關的代碼和配置統統的用版本管理工具管理起來。
總結
雖然示例程序能夠運行起來了,但我們只是來到了一個新的起點。Docker Compose 被設計來管理應用的整個生命周期,我們也可以用它來極大的提高工作效率。筆者將在接下來的文章中介紹更多 Docker Compose 相關的內容。