docker-compose入門--翻譯
在這一頁,你將學習到如何構建一個簡單的python的web應用,並通過Docker compose來執行。這個應用程式使用的是Flask
框架,並維護著一個儲存在reids裡的點選計數器。由於這個案例使用的是python,所以你其中的一些概念你必須瞭解,即使你對它不是很熟悉。
前提條件
確定你已經安裝了 Docker 引擎和Docker Compose。你不必安裝python和Redis,它們將有Docker引擎提供。
第一步:設定
定義應用的依賴。
-
為專案建立一個目錄
$ mkdir composetest $ cd composetest
-
在專案目錄下建立
app.py
的檔案,並貼上下面的內容: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)
在這個案例中,
redis
是應用網路中的redis容器的主機名。我們使用的是redis的預設埠號6379
。處理臨時錯誤
注意
get_hit_count
函式的實現。這個基本的重試迴圈讓我們能在redis服務不可用時多次重試我們的請求。當我們的應用上線時,這個操作十分有用。而且會使我們的應用更有彈性,當redis服務在應用生命週期內需要頻繁重啟時。在一個叢集中,這也幫助我們處理節點間連結瞬時斷開的場景。 -
在專案目錄中建立
requirements.txt
檔案,並貼上一下內容:flask redis
第二步:建立Dockerfile檔案
在這一步,你將編寫一個用於構建Docker映象的Dockerfile檔案。這個映象包含這個Python應用說需要的所以依賴,幷包含python本身。
在你的專案目錄下,建立一個名為Dockerfile
的檔案,然後貼上以下內容:
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]
這相當於告訴Docker要做以下事情:
- 根據Python3.7映象來構建這個映象
- 設定工作目錄為
/code
- 設定環境變數給
flask
命令使用 - 安裝gcc的so檔案、python 包(比如:MarkupSafe和 SQLAIchemy)用於編譯加速
- 複製
requirements.txt
然後安裝python依賴 - 複製宿主機當前目錄
.
到映象的工作目錄.
下 - 為容器設定預設命令
flask run
想獲得更多關於如何編寫Dockerfiles的資訊,請參閱 Docker user guide 和 Dockerfile reference.
第三步: 在Compose file 中定義服務
在專案中建立一個叫docker-compose.yml
的檔案,然後貼上以下內容:
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
這個Compose 檔案定義了兩個服務:web
和redis
。
Web 服務
這個web
服務使用之前在當前目錄的Dockerfile構建出來的映象。它將繫結及暴露容器和宿主機的5000
埠。這個案例服務使用的是Flask web服務的預設埠5000
。
Redis 服務
這個redis
服務使用的是Docker Hub 庫中的公開的 Redis映象。
第四步:通過Compose構建並執行你的應用
-
在你的工程目錄下,使用
docker-compose up
來啟動你的應用$ docker-compose up Creating network "composetest_default" with the default driver Creating composetest_web_1 ... Creating composetest_redis_1 ... Creating composetest_web_1 Creating composetest_redis_1 ... done Attaching to composetest_web_1, composetest_redis_1 web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) redis_1 | 1:C 17 Aug 22:11:10.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo redis_1 | 1:C 17 Aug 22:11:10.480 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started redis_1 | 1:C 17 Aug 22:11:10.480 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf web_1 | * Restarting with stat redis_1 | 1:M 17 Aug 22:11:10.483 * Running mode=standalone, port=6379. redis_1 | 1:M 17 Aug 22:11:10.483 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. web_1 | * Debugger is active! redis_1 | 1:M 17 Aug 22:11:10.483 # Server initialized redis_1 | 1:M 17 Aug 22:11:10.483 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled. web_1 | * Debugger PIN: 330-787-903 redis_1 | 1:M 17 Aug 22:11:10.483 * Ready to accept connections
Compose 會拉取Redis映象,然後為你的程式碼構建一個驚喜,並啟動你定義的所有服務。在這個案例中,你的程式碼將會在構建時靜態拷貝到映象中。
-
在瀏覽器中輸入 http://localhost:5000 ,你將會看到你的應用正在執行。
如果你是在你的本地使用Docker,那麼你的web 應用正在你的Docker後臺監聽5000埠。在瀏覽器上輸入 http://localhost:5000,將會看到
hello world
訊息。如果看不到,你可以嘗試輸入http://127.0.0.1:5000
。你將會看到
Hello World! I have been seen 1 times.
-
重新整理頁面。
這個數字會增長
Hello World! I have been seen 2 times.
-
切換到其他終端視窗,鍵入
docker image ls
,將會列出本地映象。列出的映象中將會看到redis
和web
。$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE composetest_web latest e2c21aa48cc1 4 minutes ago 93.8MB python 3.4-alpine 84e6077c7ab6 7 days ago 82.5MB redis alpine 9d8fa9aa0e5b 3 weeks ago 27.5MB
你可以檢查這個映象,使用如下命令
docker inspect <tag or id>
。 -
關於停止應用, 你可以在另一個終端中、你的專案目錄下執行
docker-compose down
來終止; 或者也可以在之前執行docker-compose up
的終端中鍵入 CTRL+C 來終止應用。
第五部:編輯Compose檔案,增加資料卷繫結
編輯專案目錄下的docker-compose.yml
,為web
服務增加一個繫結的資料卷。
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
environment:
FLASK_ENV: development
redis:
image: "redis:alpine"
volumes
關鍵字綁定了宿主機的專案目錄和容器內的/code
目錄,這樣就允許你快速的修改程式碼,快速生效,而不用重新構建映象了。environment
關鍵字設定了FLASK_ENV
環境變數,它用來告訴flask run
執行開發模式,並當程式碼變更時重新載入。這個模式只能用於開發。
第六步: 通過Compose重新構建和執行應用
在你的專案目錄下,鍵入docker-compose up
和更新了的Compose檔案來構建你的應用,並執行應用。
$ docker-compose up
Creating network "composetest_default" with the default driver
Creating composetest_web_1 ...
Creating composetest_redis_1 ...
Creating composetest_web_1
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
...
檢查hello wolrd
是否出現在瀏覽器上,然後重新整理瀏覽起,看數字是否增長。
共享的目錄、資料卷 和掛載繫結
如果你的專案在使用者目錄(
cd ~
)之外,那麼你需要共享出你使用的Dockerfile和資料卷的驅動或位置。如果你獲得了一個執行時錯誤,該錯誤指出應用檔案找不到、資料卷掛載被拒絕、或服務不能啟動,請嘗試使檔案或驅動能被共享。資料卷掛載需要為使用者目錄(Windows: C:\Users; Mac: /Users)之外的專案共享驅動,這對於使用Linux容器的Windows桌面Docker應用的專案是必須的。更多資訊請參考see Shared Drives on Docker Desktop for Windows, File sharing on Docker for Mac。 一些常見的案例請參考 Manage data in containers。如果你是在一個比較舊的Windows系統上使用VirtualBox,你可能會遇到一個關於共享目錄的問題,它記錄在了VB trouble ticket。新的Windows系統上因為使用的是Docker桌面應用,而不再使用VirtualBox,所以符合條件。
第七步: 升級應用
由於我們應用程式碼是掛載到容器資料卷的,你可以修改程式碼並且立刻會看到變化,而不必重新構建映象。
-
修改程式碼
app.py
中的問候方式並儲存。比如:改變Hello World
為Hello from Docker
。return 'Hello from Docker! I have been seen {} times.\n'.format(count)
-
在瀏覽器中重新整理應用,問候語應該會改變,且計數仍然增長。
第八步: 體驗一下其他的命令
如果你想在後臺執行你的服務,你可以使用-d
標籤("detached"模式)來執行docker-compose up
,然後用docker-compose ps
來檢視執行情況:
$ docker-compose up -d
Starting composetest_redis_1...
Starting composetest_web_1...
$ docker-compose ps
Name Command State Ports
-------------------------------------------------------------------
composetest_redis_1 /usr/local/bin/run Up
composetest_web_1 /bin/sh -c python app.py Up 5000->5000/tcp
docker-compose run
命令允許你為你的服務執行一次性的命令。舉個例子,檢視web
服務有哪些環境變數在生效中:
$ docker-compose run web env
docker-compose --help
可以檢視還有哪些可以使用的命令。你也可以為bash和zsh安裝 command completion,這樣也可以做到還有哪些可用的命令。
如果你是通過 compose 命令docker-compose up -d
啟動的服務,你也可以通過下面的命令來停止服務:
$ docker-compose stop
你可以關掉一切,通過down
命令,來刪除所有的容器。加入--volumns
還可以移除掉容器使用的資料卷
$ docker-compose down --volumes
這一節,你已經學會了Compose的基礎。