Docker Compose 快速入門
本教程旨在透過指導您開發一個基本的 Python Web 應用程式,介紹 Docker Compose 的基本概念。
該應用程式使用 Flask 框架,在 Redis 中設定了一個命中計數器,提供了一個關於 Docker Compose 如何應用於 Web 開發場景的實際示例。
即使您不熟悉 Python,這裡展示的概念也應該易於理解。
這是一個非規範性示例,演示了 Compose 的核心功能。
先決條件
確保您已
- 安裝了最新版本的 Docker Compose
- 對 Docker 概念以及 Docker 如何工作有基本瞭解
步驟 1:設定
為專案建立一個目錄
$ 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 f'Hello World! I have been seen {count} times.\n'
在此示例中,
redis
是應用程式網路上 redis 容器的主機名,並使用預設埠6379
。注意注意
get_hit_count
函式的編寫方式。如果 Redis 服務不可用,這個基本的重試迴圈會多次嘗試請求。這在應用程式啟動時很有用,同時也可以在應用程式生命週期內任何時間需要重啟 Redis 服務時,使應用程式更具彈性。在叢集中,這也有助於處理節點之間的瞬間連線中斷。在您的專案目錄中建立另一個名為
requirements.txt
的檔案,並將以下程式碼貼上進去flask redis
建立一個
Dockerfile
並貼上以下程式碼# syntax=docker/dockerfile:1 FROM python:3.10-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 EXPOSE 5000 COPY . . CMD ["flask", "run", "--debug"]
這告訴 Docker
- 從 Python 3.10 映象開始構建一個映象。
- 將工作目錄設定為
/code
。 - 設定
flask
命令使用的環境變數。 - 安裝 gcc 和其他依賴項
- 複製
requirements.txt
並安裝 Python 依賴項。 - 向映象新增元資料,描述容器正在監聽 5000 埠
- 將專案中的當前目錄
.
複製到映象中的工作目錄.
。 - 將容器的預設命令設定為
flask run --debug
。
重要檢查
Dockerfile
是否沒有像.txt
這樣的副檔名。一些編輯器可能會自動附加此副檔名,這將在您執行應用程式時導致錯誤。有關如何編寫 Dockerfile 的更多資訊,請參閱 Dockerfile 參考。
步驟 2:在 Compose 檔案中定義服務
Compose 簡化了對整個應用程式堆疊的控制,使得在一個單一、易於理解的 YAML 配置檔案中管理服務、網路和卷變得容易。
在您的專案目錄中建立一個名為 compose.yaml
的檔案,並貼上以下內容
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
此 Compose 檔案定義了兩個服務:web
和 redis
。
web
服務使用從當前目錄中的 Dockerfile
構建的映象。然後它將容器和主機繫結到暴露的埠 8000
。此示例服務使用 Flask Web 伺服器的預設埠 5000
。
redis
服務使用從 Docker Hub 登錄檔拉取的公共 Redis 映象。
有關 compose.yaml
檔案的更多資訊,請參閱Compose 的工作原理。
步驟 3:使用 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 映象,為您的程式碼構建一個映象,並啟動您定義的服務。在這種情況下,程式碼在構建時被靜態複製到映象中。
在瀏覽器中輸入
https://:8000/
檢視正在執行的應用程式。如果這不能解析,您也可以嘗試
http://127.0.0.1:8000
。您應該在瀏覽器中看到一條訊息
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 <標籤或 ID>
來檢查映象。停止應用程式,可以透過在第二個終端的專案目錄中執行
docker compose down
,或者在啟動應用程式的原始終端中按CTRL+C
。
步驟 4:編輯 Compose 檔案以使用 Compose Watch
編輯您專案目錄中的 compose.yaml
檔案以使用 watch
,這樣您就可以預覽正在執行的 Compose 服務,這些服務會隨著您編輯和儲存程式碼而自動更新
services:
web:
build: .
ports:
- "8000:5000"
develop:
watch:
- action: sync
path: .
target: /code
redis:
image: "redis:alpine"
每當檔案發生更改時,Compose 都會將檔案同步到容器內 /code
下的相應位置。一旦複製,打包工具會更新正在執行的應用程式而無需重啟。
有關 Compose Watch 工作原理的更多資訊,請參閱使用 Compose Watch。或者,請參閱管理容器中的資料以瞭解其他選項。
注意為了使此示例正常工作,在
Dockerfile
中添加了--debug
選項。Flask 中的--debug
選項啟用了自動程式碼過載,使得可以在不重啟或重建容器的情況下對後端 API 進行開發。更改.py
檔案後,後續的 API 呼叫將使用新程式碼,但在這個小示例中,瀏覽器 UI 不會自動重新整理。大多數前端開發伺服器都包含與 Compose 配合使用的原生即時過載支援。
步驟 5:使用 Compose 重新構建並執行應用程式
在您的專案目錄中,鍵入 docker compose watch
或 docker compose up --watch
來構建並啟動應用程式並開始檔案監視模式。
$ docker compose watch
[+] Running 2/2
✔ Container docs-redis-1 Created 0.0s
✔ Container docs-web-1 Recreated 0.1s
Attaching to redis-1, web-1
⦿ watch enabled
...
再次在 Web 瀏覽器中檢查 Hello World
訊息,並重新整理以檢視計數增加。
步驟 6:更新應用程式
要檢視 Compose Watch 的實際效果
在
app.py
中更改問候語並儲存。例如,將Hello World!
訊息更改為Hello from Docker!
return f'Hello from Docker! I have been seen {count} times.\n'
在瀏覽器中重新整理應用程式。問候語應該會更新,並且計數器應該仍在增加。
完成後,執行
docker compose down
。
步驟 7:拆分您的服務
使用多個 Compose 檔案可以讓您為不同的環境或工作流自定義 Compose 應用程式。這對於可能使用數十個容器,且所有權分佈在多個團隊的大型應用程式非常有用。
在您的專案資料夾中,建立一個名為
infra.yaml
的新 Compose 檔案。從您的
compose.yaml
檔案中剪下 Redis 服務,並將其貼上到新的infra.yaml
檔案中。請確保在檔案頂部新增services
頂級屬性。您的infra.yaml
檔案現在應該如下所示services: redis: image: "redis:alpine"
在您的
compose.yaml
檔案中,新增include
頂級屬性以及infra.yaml
檔案的路徑。include: - infra.yaml services: web: build: . ports: - "8000:5000" develop: watch: - action: sync path: . target: /code
執行
docker compose up
以使用更新後的 Compose 檔案構建並執行應用程式。您應該在瀏覽器中看到Hello world
訊息。
這是一個簡化的例子,但它演示了 include
的基本原理,以及它如何使將複雜應用程式模組化為子 Compose 檔案變得更容易。有關 include
和使用多個 Compose 檔案的更多資訊,請參閱使用多個 Compose 檔案。
步驟 8:嘗試其他一些命令
如果您想在後臺執行您的服務,您可以將
-d
標誌(用於“分離”模式)傳遞給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 docker-entrypoint.sh redis ... Up 6379/tcp composetest_web_1 flask run Up 0.0.0.0:8000->5000/tcp
執行
docker compose --help
檢視其他可用的命令。如果您使用
docker compose up -d
啟動了 Compose,請在完成後停止您的服務$ docker compose stop
您可以使用
docker compose down
命令將所有東西都停下來,並完全刪除容器。