六、Docker compose:Docker Compose 是一個用於定義和執行多容器 Docker 應用程式的工具。透過 Docker Compose,使用者可以使用一個 YAML 檔案來定義應用程式所需的所有服務,然後透過一條命令就可以建立並啟動這些服務。Docker Compose 可以極大簡化多容器應用的管理和部署流程。
它的原理,Docker Compose 主要依賴於兩個核心部分:
-
YAML 檔案 (
docker-compose.yml
):這個檔案用來描述多容器應用的各個服務以及它們之間的關係。透過定義各個服務的映象、網路、卷、埠對映等,Compose 可以在本地環境或生產環境中一致性地部署應用。 -
Docker Compose CLI:Docker 提供了一個命令列工具
docker-compose
,使用者可以透過它來管理使用docker-compose.yml
定義的服務。這些命令包括啟動、停止、重啟服務,檢視日誌等。
1. compose.yml:是 Docker Compose 用來定義多容器應用的核心配置檔案。它使用 YAML 語法描述服務、網路、卷和其他配置項。下面是一個典型的 docker-compose.yml
檔案結構及其各部分的詳細說明。
YAML 檔案不必須命名為 docker-compose.yml
,但預設情況下,Docker Compose 會在當前目錄下查詢名為 docker-compose.yml
的檔案作為配置檔案。如果想使用其他名稱的 YAML 檔案,也完全可以,只需要在執行 Docker Compose 命令時顯式指定該檔案的路徑和名稱。
version: '3.8' # 指定 Docker Compose 檔案的版本 services: # 定義服務 web: # 服務名稱,可以是任意名稱 image: nginx:alpine # 使用的映象 ports: - "8080:80" # 埠對映:將主機的8080埠對映到容器的80埠 volumes: - ./html:/usr/share/nginx/html # 掛載本地目錄到容器中的路徑 networks: - webnet # 指定服務使用的網路 depends_on: - app # 指定依賴的服務,確保app服務在web服務之前啟動 app: # 另一個服務 build: ./app # 使用本地的Dockerfile構建映象 command: python app.py # 覆蓋預設命令 volumes: - ./app:/app # 掛載本地目錄到容器中 environment: - DEBUG=1 # 設定環境變數 networks: - webnet # 指定服務使用的網路 volumes: # 定義資料卷 db_data: # 卷名稱,可以在 services 中引用 driver: local # 指定驅動型別,這裡是本地驅動 networks: # 定義網路 webnet: # 網路名稱 driver: bridge # 指定網路驅動型別
version
version
定義了 docker-compose.yml
檔案的版本,版本決定了可以使用的語法和功能。常見版本包括 '3.8'
、'3'
、'2'
等。一般建議使用較新的版本以確保相容最新功能。
services
services
是最核心的部分,定義了應用中所有的服務。每個服務包含以下常用配置項:
image
: 指定要使用的 Docker 映象。如果該映象不存在,Compose 會自動從 Docker Hub 拉取。build
: 如果你希望構建自己的映象,可以使用build
選項,通常指定一個包含Dockerfile
的路徑。ports
: 埠對映,HOST:CONTAINER
格式,將主機的埠對映到容器內的埠。volumes
: 卷掛載,HOST_PATH:CONTAINER_PATH
格式,將主機的目錄或檔案掛載到容器內。networks
: 指定服務使用的網路。可以在下面的networks
部分定義這些網路。environment
: 設定環境變數,可以在容器內訪問這些變數。depends_on
: 指定服務之間的依賴關係,確保某些服務在其他服務啟動之前啟動。command
: 覆蓋預設的容器啟動命令。restart
: 定義容器的重啟策略(如always
、on-failure
)。
volumes
volumes
用於定義和管理資料卷。資料卷用於持久化資料,即使容器被刪除,資料仍然存在。
driver
: 定義卷的驅動型別,預設是local
。
卷可以在 services
中引用,作為資料儲存的路徑。
networks
networks
用於定義服務之間的網路配置。
driver
: 指定網路驅動型別,常見的有bridge
、overlay
等。
網路可以被多個服務共享,用於服務之間的通訊。
2.常用基礎命令:Docker Compose 的命令大多數是在專案的根目錄下執行的,該目錄包含 docker-compose.yml
檔案。Docker Compose 會自動在當前目錄查詢 docker-compose.yml
檔案,並根據其中定義的內容執行相關操作。
# 啟動應用:命令會讀取當前目錄下的 docker-compose.yml
檔案,並啟動所有定義的服務。如果服務所需的映象不存在,Compose 會自動構建或拉取映象。如果想在後臺執行,可以加上 -d 引數
docker compose up -d
# 啟動已經存在的容器,而不會重新建立它們。如果容器已經存在但未執行,此命令可以用來重新啟動它們。
docker compose start
# 命令會停止所有正在執行的服務
docker compose stop
# 重啟服務,且在不指定服務名稱,docker-compose 將重啟所有服務
docker compose restart [SERVICE_NAME]
# 列出當前所有服務的狀態
docker compose ps
# 看指定服務的日誌。如果不指定服務名稱,則會檢視所有服務的日誌
docker compose logs [SERVICE_NAME]
# 執行一次性命令
docker compose run SERVICE_NAME COMMAND
# 在正在執行的容器中執行命令
docker compose exec
# 在 docker-compose.yml 中定義了 build 選項,可以用這個命令來構建映象
docker compose build
# 停止並刪除所有在 docker-compose.yml
中啟動的服務、網路和掛載的卷。如果你想刪除服務但保留卷資料,可以加上 --volumes
選項
docker compose down --volumes
其中,docker compose up有幾個引數要重點講下
# --scale SERVICE=NUM:指定服務的容器數量,例如可以擴充套件 web 服務到 3 個副本。 docker compose up --scale web=3 # 制構建服務映象,即使映象已經存在 docker compose up --build # 刪除不在 docker-compose.yml 檔案中的多餘容器 docker compose up --remove-orphans
2. 使用流程
- 定義應用環境:在
docker-compose.yml
檔案中定義應用程式所需的各個服務。 - 啟動應用:使用
docker-compose up
命令啟動整個應用,Compose 會根據docker-compose.yml
檔案建立並啟動所有服務。 - 管理服務:使用
docker-compose
提供的其他命令,如stop
,start
,restart,scale
等來管理已經啟動的服務。 - 刪除應用:透過
docker-compose down
命令停止並刪除所有服務及其相關資源。
3.實踐
假設有一個前後端分離的 Python + Django + MySQL + Redis + Vue + Nginx 專案,我們需要為各個元件編寫Dockerfile,並在 docker-compose.yml
檔案中配置服務。
目錄結構:
myproject/ ├── backend/ │ ├── Dockerfile │ ├── myproject/ │ ├── manage.py │ ├── requirements.txt ├── frontend/ │ ├── Dockerfile │ ├── package.json │ ├── src/ │ └── ... ├── nginx/ │ ├── Dockerfile │ ├── nginx.conf ├── docker-compose.yml
3.1 Backend(Django)部分
backend/Dockerfile:
# 使用官方的 Python 映象作為基礎映象 FROM python:3.9-slim # 設定工作目錄 WORKDIR /app # 複製依賴檔案並安裝 COPY requirements.txt /app/ RUN pip install --no-cache-dir -r requirements.txt # 複製應用程式碼 COPY . /app/ # 暴露應用埠 EXPOSE 8000 # 執行 Django 開發伺服器(你可能需要使用 gunicorn 或者其他 WSGI 伺服器在生產環境中) CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"]
backend/requirements.txt,
在這個檔案中,列出 Django 專案所需的所有 Python 包,如:
Django>=3.2,<4.0
mysqlclient
redis
gunicorn
3.2 Frontend(Vue.js)部分
frontend/Dockerfile:
# 使用 Node.js 映象作為基礎映象 FROM node:14-alpine # 設定工作目錄 WORKDIR /app # 複製依賴檔案並安裝 COPY package.json yarn.lock /app/ RUN yarn install # 複製原始碼 COPY . /app/ # 構建 Vue.js 應用 RUN yarn build # 執行 Vue.js 應用(在開發時可能用 npm run serve;在生產環境中通常用 nginx 或 serve 靜態資源) EXPOSE 8080 CMD ["yarn", "serve"]
3.3 Nginx 部分
nginx/Dockerfile:
# 使用官方 Nginx 映象作為基礎映象 FROM nginx:alpine # 刪除預設的配置檔案 RUN rm /etc/nginx/conf.d/default.conf # 複製自定義的 Nginx 配置檔案 COPY nginx.conf /etc/nginx/conf.d/ # 複製前端構建的靜態檔案到 Nginx 容器 COPY --from=frontend /app/dist /usr/share/nginx/html # 暴露埠 EXPOSE 80
nginx/nginx.conf: 這是一個 Nginx 配置檔案的示例,反向代理到 Django 和 Vue.js 應用
server { listen 80; # 靜態檔案處理(Vue.js) location / { root /usr/share/nginx/html; try_files $uri $uri/ /index.html; } # 代理請求到 Django 應用 location /api/ { proxy_pass http://backend:8000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
3.4 Docker Compose 檔案
docker-compose.yml:
version: '3.8' services: db: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: mydatabase MYSQL_USER: myuser MYSQL_PASSWORD: mypassword volumes: - db_data:/var/lib/mysql networks: - backend redis: image: redis:alpine restart: always networks: - backend backend: build: ./backend command: ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"] volumes: - ./backend:/app ports: - "8000:8000" environment: - DATABASE_HOST=db - DATABASE_PORT=3306 - DATABASE_NAME=mydatabase - DATABASE_USER=myuser - DATABASE_PASSWORD=mypassword - REDIS_HOST=redis - REDIS_PORT=6379 depends_on: - db - redis networks: - backend frontend: build: ./frontend volumes: - ./frontend:/app ports: - "8080:8080" networks: - frontend nginx: build: ./nginx ports: - "80:80" depends_on: - frontend - backend networks: - frontend - backend volumes: db_data: networks: frontend: backend:
啟動專案:在 myproject/
目錄下執行命令:docker compose up --build -d. 啟動所有服務。透過 http://localhost
訪問前端應用,後端 API 在 http://localhost/api/
路徑下。