Dockers Compose常用指令
1、常用指令介紹
1.1、version
指令
頂級一級指令,指定 compose 指定文件格式版本
version: "3.8"
services:
不同版本支持的功能不同。常用版本有 ‘2’, ‘3’, ‘3.8’ 等。
1.2、services
指令
頂級一級指令,定義應用程序的各個服務(容器),每個服務對應一個容器。
version: "3.8"
services: 容器1: 各種配置項.....容器2: 各種配置項.....
常用服務配置項:
-
image: 指定使用的鏡像,如
nginx:alpine
-
container_name:指定容器名稱,如
my_redis
-
build: 指定構建鏡像的 Dockerfile 路徑
build
指令用于指定如何構建一個服務所依賴的鏡像。你可以通過這個指令來定義構建上下文、Dockerfile 路徑以及構建參數等。主要用途
- 自定義鏡像構建:允許你從源代碼或特定的基礎鏡像開始構建自己的 Docker 鏡像。
- 靈活的構建配置:可以根據不同的環境或需求調整構建參數和配置。
build:context: ./dir # Dockerfile 所在目錄# 多環境構建,可選,指定哪個 Dockerfile 進行構建,默認 Docker 會尋找工作目錄下的 Dockerfile 文件。dockerfile: Dockerfile-dev # 定義構建時變量,對應Dockerfile中的 ARG 指令,允許你在構建時傳遞構建參數args: buildno: 1# 列出可以作為緩存來源的鏡像列表,加速構建過程。cache_from:- user/app:v1# 在鏡像上添加元數據標簽。labels:- "com.example.description=Accounting webapp"# 設置 /dev/shm 的大小,對于某些應用可能需要更大的共享內存空間。shm_size: '2gb'# 資源限制ulimits: nproc: 65535nofile:soft: 20000hard: 40000# 可選,多階段構建目標階段,用于多階段構建,指定構建目標階段,可顯著減小最終鏡像大小(多層構建,可以指定構建哪一層)target: production # 是否禁用緩存no_cache: false# 安全構建security_opt:- seccomp=unconfinedextra_hosts:- "somehost:162.242.195.82"
多階段構建優化
# Dockerfile FROM node:14 as builder WORKDIR /app COPY . . RUN npm install && npm run buildFROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html# docker-compose.yml services:web:build:context: .target: builder # 只構建builder階段
構建控制命令
# 構建但不啟動: docker-compose build # 強制重建: docker-compose build --no-cache # 構建特定服務: docker-compose build webapp # 查看構建參數: docker-compose config --services
最佳實踐
-
上下文優化:
- 使用
.dockerignore
文件減少上下文大小 - 避免包含
node_modules
等大目錄
- 使用
-
構建緩存利用:
build:cache_from:- myapp:latest
-
多階段構建:
- 分離構建環境和運行環境
- 顯著減小最終鏡像大小
-
參數化構建:
build:args:- VERSION=${TAG:-latest}
如何查看構建過程輸出?
docker-compose build --no-cache --progress=plain
docker-compose build
本質上是調用docker build
,但提供了更便捷的項目級構建管理。
-
restart: 重啟策略
restart: always # no, always, on-failure, unless-stopped
-
ports: 端口映射,格式
HOST:CONTAINER
ports:- "80:80" # 映射所有接口的80端口- "127.0.0.1:8000:8000" # 只映射本地回環地址
-
volumes
卷掛載。
volumes:- /var/lib/mysql # 1、匿名卷- ./data:/var/lib/mysql # 2、主機路徑掛載- db-data:/var/lib/mysql # 3、命名卷
實際當中,選擇上述3種的1種即可
重要-注意:
截止到文檔的這個位置,上述介紹的指令,除了
build
指令外,其它指令是編寫docker-compose.yml 文件必寫的指令。如果使用別人制作好的鏡像,我們就不需要
build
指令。下面羅列常用可選的指令。
常用服務可選配置項:
-
environment: 環境變量
environment:RACK_ENV: developmentSHOW: 'true'
或使用文件:
env_file:- .env
Tips:
簡單近似的理解為定義容器性全局的變量,對 Java 來說,可以使用
system.getProperty("pname")
來獲取;對于 Python 來說,可以使用os.getenv("pname")
來獲取;對于 MySql 來說,可以設置初始化數據庫的 root 密碼等等之類的。具體使用見總結的environment部分
。 -
depends_on: 服務依賴
depends_on:- db- redis
其作用就是,等待 db 和 redis 容器服務啟動之后。關閉時,先關閉主服務,再關閉 db 和 redis 服務。
-
networks: 加入的網絡
networks:- frontend- backend
其作用就是,使用我們自己預先定義好的網絡。
-
command: 覆蓋默認命令
command: bundle exec thin -p 3000
-
**devices:**指定設備映射列表。
devices:- "/dev/ttyUSB0:/dev/ttyUSB0"
-
**dns:**自定義 DNS 服務器,可以是單個值或列表的多個值。
dns: 8.8.8.8dns:- 8.8.8.8- 9.9.9.9
-
**dns_search:**自定義 DNS 搜索域。可以是單個值或列表。
dns_search: example.comdns_search:- dc1.example.com- dc2.example.com
-
privileged: 覆蓋默認命令
在Docker Compose配置文件中,
privileged
是一個布爾類型的選項,用于給容器提供擴展權限。當設置為true
時,這個選項允許容器獲得幾乎所有的能力(capabilities),并且禁用了安全機制如AppArmor、SELinux以及seccomp的限制。簡單來說,它使得容器內的進程擁有類似宿主機上運行的進程的權限。作用
- 增強容器權限:通過給予容器更廣泛的權限,可以執行需要更高權限的操作,例如直接訪問硬件資源或執行系統管理任務。
- 支持特定應用需求:某些應用程序可能需要比默認提供的更多權限才能正常工作,比如網絡監控工具、虛擬化軟件等。
- 開發與調試:在開發和調試過程中,有時需要對系統進行深層次的操作,此時使用特權模式可以使這一過程更加方便。
- 獲得root權限:容器內的root用戶擁有宿主機的root權限。
- 繞過安全機制:忽略很多默認的Docker安全限制。
- 解除大部分限制:容器幾乎可以訪問宿主機的所有設備和內核功能。
使用示例
version: '3.8' services:myservice:image: myimageprivileged: true
特權模式的作用
services:# 1. 允許訪問所有設備docker-in-docker:image: docker:dindprivileged: true # 必須啟用才能運行Docker-in-Docker# 2. 允許修改內核參數network-tool:image: network-toolsprivileged: true # 需要修改網絡棧參數# 3. 允許加載內核模塊device-driver:image: custom-driverprivileged: true # 需要加載內核模塊
安全風險警告:
特權模式會帶來嚴重安全風險:
- 容器逃逸:攻擊者可能從容器獲取宿主機root權限
- 系統破壞:惡意容器可能破壞宿主機系統
- 數據泄露:可以訪問宿主機的所有數據
替代方案(更安全的選擇)
services:# 1. 精細控制能力device-access:image: device-toolcap_add:- SYS_ADMIN # 只添加需要的權限- NET_ADMIN- ALL # 開啟全部權限cap_drop:- SYS_PTRACE # 關閉 ptrace權限devices:- "/dev/ttyUSB0:/dev/ttyUSB0" # 只掛載需要的設備# 2. 特定設備訪問gpio-service:image: gpio-controldevices:- "/dev/gpiomem:/dev/gpiomem"
實際應用場景
services:# 1. 必須使用特權模式的場景kubelet:image: kubeletprivileged: true # Kubernetes組件需要# 最佳實踐建議 # 審計特權容器 docker ps --filter 'label=privileged=true' # 結合用戶命名空間 userns_mode: "host" # 與privileged一起使用更安全
特權模式的技術細節
當
privileged: true
時,容器會:- 獲得所有Linux capabilities(約40種)
- 可以訪問所有設備文件(如
/dev/mem
) - 可以修改AppArmor/SELinux配置
- 可以掛載任意文件系統
檢查容器權限:
# 檢查容器是否特權模式運行 docker inspect --format='{{.HostConfig.Privileged}}' <container> # 查看授予的capabilities docker inspect --format='{{.HostConfig.CapAdd}}' <container>
企業級安全建議:
- 集群部署時:使用PodSecurityPolicy/OPA Gatekeeper禁止特權容器
- CI/CD管道中:添加特權模式檢查步驟
- 監控方面:對特權容器進行特別審計
- 替代架構:考慮使用無特權容器設計
-
stdin_open:控制標準輸入(STDIN)行為的配置項
stdin_open
是一個在 Docker Compose 文件中用于服務配置的選項,它保持容器的標準輸入(stdin)打開。默認情況下,Docker 容器啟動時并不會保持標準輸入打開,這意味著一旦啟動命令執行完畢,如果沒有其他進程繼續保持容器運行,容器將會退出。通過設置
stdin_open: true
,你可以讓容器的標準輸入保持打開狀態,這通常與-i
參數在docker run
命令中的作用相似,允許你以交互模式與容器進行通信。使用場景
- 交互式應用程序:如果你的應用程序需要從標準輸入讀取數據(例如某些CLI工具或交互式的shell),你需要確保容器的標準輸入是打開的。
- 調試:對于開發和調試來說,有時需要保持容器的輸入流開放以便手動發送命令或信息到容器內。
示例
下面是一個簡單的例子展示了如何在 Docker Compose 文件中使用
stdin_open
:version: '3.8' services:myservice:image: ubuntustdin_open: true # 保持標準輸入打開tty: true # 分配一個偽TTY,通常與stdin_open一起使用,提供交互界面command: /bin/bash
在這個例子中,我們使用了 Ubuntu 鏡像,并且通過設置
stdin_open: true
和tty: true
來保持標準輸入打開并分配一個偽TTY。這樣做的結果是當你運行這個 Compose 文件時,它會啟動一個可以交互的 Bash shell,讓你能夠直接與容器內部進行交互。核心作用
services:# 1. 啟用交互式會話python:image: python:3stdin_open: true # 允許輸入Python代碼,例如:docker-compose run python python3(進入交互式Python解釋器)tty: true# 2. 保持后臺容器的輸入能力shell:image: alpinestdin_open: truecommand: /bin/sh # 保持shell運行
與
tty
的區別配置項 作用 典型使用場景 stdin_open: true
保持輸入流開放 需要向容器發送輸入 tty: true
分配偽終端 需要終端特性(如clear、Ctrl+C) 請注意,雖然
stdin_open
可以為你的容器提供更多的交互性,但在生產環境中通常不需要這樣做,因為大多數服務應用并不需要直接的用戶交互。因此,該選項更多地適用于開發、測試或需要直接與容器交互的場景。實際應用場景
services:# 1. 開發環境調試dev:build: .stdin_open: true # 允許輸入測試數據tty: true# 2. 數據庫管理控制臺mysql-client:image: mysqlcommand: mysql -uroot -pstdin_open: true # 允許輸入密碼# 3. 交互式教學環境tutorial:image: learnpythonstdin_open: true # 允許學生輸入代碼tty: true## 最佳實踐 # 1、生產環境應禁用(除非明確需要):stdin_open: false(顯式關閉更安全) # 2、開發環境按需啟用:stdin_open: ${ENABLE_INTERACTIVE:-false}(通過環境變量控制) # 3、結合 docker-compose run 使用: docker-compose run --service-ports web bash # 交互式訪問
與
docker exec -it
的區別?stdin_open
是創建時的配置exec -it
是后期附加到運行中容器
-
tty:虛擬終端
設置為
true
時,它會為容器分配一個虛擬終端(TTY)。這個選項通常與stdin_open: true
一起使用,以便提供交互式的 shell 或命令行界面。類似于 Dockers 如下命令:
docker exec -it <container> sh # 后期附加終端
-
security_opt:安全配置
-
security_opt
是 Docker Compose 中用于配置容器安全選項的重要參數,它允許你精細控制容器的安全設置,特別是與 Linux 安全模塊(如 SELinux 和 AppArmor)的交互方式。security_opt
允許你:設置 SELinux 標簽、配置 AppArmor 策略、調整容器能力(capabilities)、禁用默認的安全配置基礎語法
services:secured-service:image: nginxsecurity_opt:- label:user:USER # SELinux用戶標簽- label:role:ROLE # SELinux角色標簽- label:type:TYPE # SELinux類型標簽- label:level:LEVEL # SELinux級別標簽- apparmor=PROFILE # AppArmor配置- no-new-privileges # 禁止特權升級- seccomp=PROFILE.json # seccomp配置
核心安全選項
# 1. SELinux 標簽控制 security_opt:- label:user:system_u- label:role:object_r- label:type:svirt_lxc_net_t- label:level:s0:c100,c200
**Tips: **
可以理解為設置 Linux 系統的SELinux 參數;
SELinux 選項:
label:user
設置用戶標簽 system_u
label:role
設置角色標簽 object_r
label:type
設置類型標簽 svirt_lxc_net_t
label:level
設置MLS/MCS級別 s0:c100,c200
-
links:安全配置
links
字段用于定義服務之間的鏈接。通過這種方式,可以允許一個服務連接到另一個服務,并且能夠使用服務名稱作為主機名來訪問被連接的服務。這個概念源自于較早版本的 Docker 網絡模型,它創建了容器間的依賴關系,并提供了服務發現機制。links
在傳統 Docker 部署中曾非常重要,但在現代 Docker 網絡中,建議優先考慮使用自定義網絡實現服務發現和連接。作用
- 服務發現:通過
links
,你可以使用被鏈接服務的名字作為主機名來訪問該服務。這對于那些需要明確知道如何連接到其他服務的應用來說非常有用。 - 環境變量注入:鏈接還會在目標容器中創建一系列環境變量,這些變量包含了關于鏈接服務的信息(如端口、IP地址等)。不過,這種方法現在被認為不如使用自定義網絡那樣靈活和透明。
- 網絡隔離與互通:盡管 Docker 的默認行為是讓所有在同一自定義網絡上的服務自動相互可見,但
links
可以用來更精細地控制這種可見性,尤其是在使用默認橋接網絡時。
注意事項
-
在現代 Docker 使用中,推薦的方式是通過定義自定義網絡來實現服務間通信,而不是使用
links
。這是因為自定義網絡提供了更加靈活的服務發現機制,并且支持更為復雜的網絡配置,同時避免了使用links
帶來的某些限制和復雜性。 -
自 Docker 網絡功能增強以來,
links
已經不再推薦用于新的項目中。自定義網絡不僅簡化了多服務應用的網絡配置,還提高了其可維護性和擴展性。 -
推薦使用自定義網絡,了解即可,老的項目中可能還在使用。
- 服務發現:通過
1.3、volumes
指令
在 Docker Compose 文件中,volumes
是一個非常重要的配置項,它用于管理容器與主機之間的數據持久化和共享。
基本概念
volumes (卷) 在 Docker 中有兩個主要用途:
- 數據持久化:容器停止或刪除后,數據不會丟失
- 數據共享:在容器之間或容器與主機之間共享數據
三種主要類型
在 docker-compose.yml 中,volumes 可以分為三種類型:
1. 匿名卷 (Anonymous volumes)
volumes:- /var/lib/mysql
- 沒有指定名稱,由 Docker 自動管理
- 數據會持久化,但不易查找和管理
- 容器刪除后,需要通過
docker volume prune
清理
Tips:
也就是說,我只是在
容器里內
聲明了一個數據卷而已,對應宿主機的位置,由宿主機的docker
自己管理,一般是在 宿主機的
/var/lib/docker/volumes/<volume_name>/_data
這個地方,且名字是一串隨機哈希(如
3a9f8e8b...
),所以不易查找和管理。
2. 命名卷 (Named volumes)
在文件頂部需要先聲明:
volumes:db-data:
然后才可以在容器服務中使用:
version "3.8"
service: mysql:image: mysql:latestvolumes:- db-data:
- 由 Docker 管理,存儲在
/var/lib/docker/volumes/
目錄下 - 最適合生產環境使用,易于管理和備份
Tips:
可以近似的簡單的理解為和
匿名卷
其實是一樣的,也是由宿主機的docker
自己管理,也是在宿主機的
/var/lib/docker/volumes/<volume_name>/_data
這個地方,只不過匿名卷
的名稱是一串 隨機哈希值 ,而 命名卷 是我們在文件中申明的名稱而已,所以易于查找和管理。
3. 主機綁定掛載 (Host bind mounts)
就是直接綁定 宿主機的目錄
和 容器里目錄
的映射關系。
version "3.8"
service: mysql:image: mysql:latestvolumes:- ./data:/var/lib/mysql
- 直接映射主機文件系統的目錄到容器
- 適合開發環境,可以實時修改代碼或配置
- 路徑可以是絕對路徑或相對路徑(相對于 compose 文件位置)
高級配置選項
-
只讀掛載
volumes:- ./config:/etc/config:ro
添加
:ro
表示容器只能讀取不能修改 -
自定義卷驅動
volumes:db-data:driver: localdriver_opts:type: 'nfs'o: 'addr=10.40.0.199,nolock,soft,rw'device: ':/path/to/dir'
-
卷標簽
volumes:db-data:labels:- "com.example.description=Database volume"
1.4、networks
指令
networks
指令用于定義和管理服務之間的網絡連接。通過使用 networks
,你可以創建自定義的網絡來控制哪些服務可以相互通信以及如何通信。這提供了比默認網絡配置更高級的網絡管理功能,使得容器間的互聯更加靈活、安全。
作用
- 隔離與分段:允許你根據需要將服務劃分為不同的網絡,從而實現網絡層面的服務隔離。
- 自定義網絡驅動:支持使用不同的網絡驅動(如 bridge, overlay 等),以適應不同的部署場景。
- DNS解析:在同一網絡中的服務可以通過服務名稱自動解析為對應的容器 IP 地址,簡化了服務發現過程。
- 外部訪問:可以將某些網絡設置為外部可訪問,這樣就可以從宿主機或其他非 Docker Compose 定義的容器訪問這些服務。
核心網絡類型
網絡類型 | 特點 | 適用場景 |
---|---|---|
bridge (默認) | 單主機虛擬網絡,自動DNS解析 | 開發環境,單機部署 |
overlay | 多主機網絡,支持集群 | Swarm集群部署 |
host | 直接使用主機網絡棧 | 高性能需求,端口沖突避免 |
macvlan | 為容器分配MAC地址 | 需要直接接入物理網絡 |
none | 完全禁用網絡 | 特殊安全需求 |
基本用法
如何定義和使用自定義網絡:
version: '3.8'
services:web:image: example/web:latestnetworks:- frontend- backendadmin:image: example/admin:latestnetworks:- backend
networks:frontend: # 網絡名稱driver: bridge # 網絡驅動類型driver_opts: # 驅動選項com.docker.network.bridge.name: my-bridgeattachable: true # 是否允許其他容器附加internal: false # 是否內部網絡(無外部訪問)labels: # 元數據- "com.example.description=Frontend network"backend:driver: bridge
說明:定義了兩個網絡:frontend
和 backend
。web
服務同時連接到這兩個網絡,而 admin
服務僅連接到 backend
網絡。這意味著 web
服務可以通過網絡名稱作為主機名與 admin
服務進行通信,但 admin
服務不能直接與 web
服務通信(除非也加入 frontend
網絡)。
高級用法
-
指定靜態IP地址:在某些情況下,你可能希望為服務分配一個靜態IP地址。雖然這不是所有網絡驅動都支持的功能,但在某些特定環境下是可行的。
networks:app_net1:driver: bridgeipam:config:- subnet: 172.20.0.0/16app_net2:ipam:driver: defaultconfig:- subnet: 172.20.0.0/24gateway: 172.20.0.1ip_range: 172.20.0.128/25 services:app:image: example/app:latest# 服務特定配置networks:app_net1:ipv4_address: 172.20.1.10aliases: # 額外域名別名- database- mysql
-
外部網絡:如果你想要連接到已經存在的 Docker 網絡,可以將網絡標記為外部。
# 這表示該服務將會連接到名為 my-pre-existing-network 的現有 Docker 網絡,而不是創建一個新的網絡。 networks:default:external:name: my-pre-existing-network # 使用已存在的網絡
-
別名:你還可以給服務在網絡中的名字設置別名,以便于其他服務更容易地找到它。
services:some-service:networks:some-network:aliases:- alias1- alias3other-network:aliases:- alias2
在這個例子中,
some-service
在some-network
網絡中有兩個別名alias1
和alias3
,而在other-network
中有一個別名alias2
。
實際應用場景
1. 多網絡隔離
services:web:networks:- frontenddb:networks:- backend
networks:frontend:backend:
2. 微服務架構
services:gateway:networks:- ingressservice1:networks:- ingress- service_netservice2:networks:- service_net
networks:ingress:service_net:
3. 生產環境配置
networks:app_net:driver: overlayattachable: trueipam:config:- subnet: 10.0.1.0/24
網絡連接原理
-
DNS解析:
- 同一網絡內可通過服務名或容器名訪問
- 自動負載均衡(多個容器實例時)
-
端口訪問:
- 同一網絡內無需發布端口即可相互訪問
- 跨網絡或外部訪問需要
ports
映射
-
連接隔離:
networks:secure_net:internal: true # 禁止外部訪問
操作命令
# 1、查看網絡:
docker network ls
docker network inspect <network_name>
# 2、連接/斷開容器:
docker network connect <network> <container>
docker network disconnect <network> <container>
# 3、清理未用網絡:
docker network prune
最佳實踐
# 1、環境隔離:
networks:dev_net:prod_net:
# 2、安全分層:
services:api:networks:- api_netdb:networks:- db_net
# 3、Swarm模式:
networks:cluster_net:driver: overlayattachable: true
Tips:
1、不定義networks會怎樣?
Compose會創建默認的bridge網絡,所有服務加入其中(不推薦生產環境使用)
2、如何實現容器與主機通信?
使用
host
網絡或通過主機IP訪問:services: app:network_mode: host
3、跨Compose項目的網絡共享?
networks: shared_net:external: truename: project1_shared_net
4、與Kubernetes網絡的對比?
Docker網絡更簡單直接,K8s網絡插件(如Calico、Flannel)提供更復雜的策略控制。
總結
通過合理利用 networks
指令,不僅可以更好地組織和隔離應用的不同部分,還能增強安全性并簡化服務發現過程。這對于構建復雜的應用架構尤其重要,因為它提供了一種有效的方式來管理和優化容器間的網絡交互。
1.5、高級配置
1.5.1、健康檢查
在Docker Compose配置文件中,healthcheck
指令用于定義容器的健康檢查機制。這個機制允許你檢查你的服務容器是否已經準備好接受流量,即容器中的應用程序是否正在按預期運行,可以自動檢測容器內的應用是否真正"就緒"而不僅僅是容器進程是否運行。通過這種方式,可以確保服務之間的依賴關系只有在相關服務完全準備好之后才進行連接,從而避免了服務啟動順序帶來的問題。
健康檢查通過定期執行命令來:
- 驗證服務可用性:比如數據庫是否能接受連接
- 控制啟動依賴:確保一個服務等待另一個服務真正準備好
- 自動恢復:與
restart
策略配合可實現故障自愈
基礎語法
services:web:healthcheck:test: ["CMD", "curl", "-f", "http://localhost"] # 檢查命令interval: 30s # 檢查間隔timeout: 10s # 命令超時時間retries: 3 # 失敗重試次數start_period: 5s # 容器啟動后的初始化時間(期間不標記失敗)
檢查方式
1. 命令檢查(推薦)
healthcheck:test: ["CMD", "pg_isready", "-U", "postgres"] # PostgreSQL檢查# 或test: ["CMD-SHELL", "mysqladmin ping -uroot -p${MYSQL_ROOT_PASSWORD}"] # MySQL
2. 禁用健康檢查
healthcheck:disable: true
3. TCP端口檢查
healthcheck:test: ["TCP", "8080"] # 只檢查端口是否監聽
實際應用示例
- MySQL 健康檢查
services:db:image: mysql:8.0healthcheck:test: ["CMD-SHELL", "mysqladmin ping -uroot -p$$MYSQL_ROOT_PASSWORD"]interval: 5stimeout: 5sretries: 3
- Web 應用健康檢查
services:web:build: .healthcheck:test: ["CMD", "curl", "-f", "http://localhost:3000/health"]start_period: 10s # 給應用啟動時間
健康狀態的影響
docker-compose ps
顯示狀態:
Name Command State Ports
-------------------------------------------------------------------
web npm start Up (healthy) 0.0.0.0:3000->3000/tcp
db docker-entrypoint.sh Starting (unhealthy)
- 服務依賴控制:
services:app:depends_on:db:condition: service_healthy
- 集群編排:Swarm/K8s 會根據健康狀態決定是否路由流量
高級配置技巧
- 自定義健康端點(Web應用)
// Express示例
app.get('/health', (req, res) => {db.ping() // 檢查數據庫連接.then(() => res.status(200).send('OK')).catch(() => res.status(503).send('Service Unavailable'))
})
- 復合檢查
healthcheck:test: ["CMD-SHELL", "test -f /tmp/ready && curl -f http://localhost"]
- 日志調試
docker inspect --format='{{json .State.Health}}' <container># 查看健康檢查日志?
docker logs <container> 2>&1 | grep healthcheck# 生產環境建議配置?
healthcheck:test: ["CMD", "custom-health-check-script.sh"]interval: 30stimeout: 15sretries: 5start_period: 60s # 給復雜應用足夠的啟動時間
例子:
version: "3.8"
services:web:image: my-web-apphealthcheck:test: ["CMD-SHELL", "curl -f http://localhost/ || exit 1"]interval: 1m30stimeout: 10sretries: 3start_period: 40s
Tips:
用的情況應該比較少和簡單。
1.5.2、資源限制
資源限制(resource constraints)是指對服務容器所能夠使用的計算資源進行限制。這些資源包括CPU、內存等,通過設置這些限制,可以控制容器的資源使用情況,從而優化性能、避免某個容器過度消耗資源而影響其他容器或主機系統的正常運行。
在Docker Compose文件中,可以通過deploy.resources
字段來指定資源限制和預留值,不過請注意,deploy
字段主要用于Swarm模式下,如果你不使用Swarm集群而是直接使用Docker Compose,則需要確保你的Compose版本支持這些選項,并且正確地應用它們。
非Swarm模式使用resources
而非deploy.resources
。
例如
services:my_service:image: my_imagedeploy:resources:# 可以使用相對單位如1.0代表單個CPU的核心limits:memory: 512M # 限制一個服務最多使用512MB的RAMcpus: '0.5' # 限制一個服務使用不超過0.5個CPU核心pids: 100 # 最大進程數devices:- capabilities: ["gpu"] # GPU限制# 除了限制以外,還可以設置資源預留,確保容器至少有這么多資源可用。這對于保證關鍵服務的性能非常有用reservations:cpus: '0.2' # 保證至少0.2個CPU核心memory: 256M # 保證分配的最小內存
上述deploy
字段中的資源管理特性主要針對Docker Swarm環境。如果你僅使用Docker Compose而不打算部署到Swarm集群中,確保你的使用場景與Compose版本相匹配。對于非Swarm環境下的資源限制,可以在創建容器時直接使用resources
字段,但具體的語法和支持可能會有所不同。
實際應用場景
1. 生產環境數據庫配置
services:mysql:deploy:resources:limits:cpus: '2'memory: 4Gpids: 500reservations:memory: 2G
2. 微服務資源配額
services:api:deploy:resources:limits:cpus: '1'memory: 1Gdepends_on:redis:condition: service_healthyredis:deploy:resources:limits:memory: 500M
資源限制工作原理
- Linux底層機制:
- 內存:
cgroups memory subsystem
- CPU:
CFS scheduler
- 設備:
device cgroup controller
- 內存:
- Docker實現:
- 限制是硬性的,超用會觸發OOM Killer(內存)或節流(CPU)
- 保留(reservations)是軟性的,只在資源爭用時生效
查看資源使用情況
# 查看容器資源統計
docker stats
# 詳細資源分配信息
docker inspect <container> | grep -i resources -A 20
# 查看cgroup配置
docker exec <container> cat /sys/fs/cgroup/memory/memory.limit_in_bytes
最佳實踐建議
# 1、內存限制:始終設置內存限制防止系統崩潰;預留10-20%給系統進程
memory: ${MEM_LIMIT:-500M}# 2、CPU限制:對計算密集型服務使用小數核心(如0.3);對延遲敏感服務使用cpuset固定CPU核心
cpus: '0.3'
cpuset: '0,1' # 綁定到特定核心# 3、混合部署:
services:frontend:deploy:resources:limits:cpus: '0.2'memory: 200Mbackend:deploy:resources:limits:cpus: '1'memory: 1G
1.5.3、擴展字段
擴展字段是 Docker Compose 文件中以 x-
開頭的自定義配置項,它們允許你在不破壞 Compose 文件規范的情況下添加自己的元數據或配置。
作用
- 增強靈活性:擴展字段允許你在Docker Compose文件中包含更多的元數據或配置細節,而不受限于官方指定的格式和結構。
- 工具支持:一些第三方工具或腳本可能會解析這些擴展字段,以便執行特定的任務或操作。例如,某些CI/CD管道可能會讀取這些字段來決定構建或部署的行為。
- 文檔與注釋:雖然不是其主要用途,但有時也會用擴展字段來為配置添加注釋或說明,幫助理解復雜的配置。
直接配置
version: '3.8'
services:web:image: example/web:latestx-custom-labels:- "environment": "production"- "team": "backend"deploy:resources:limits:cpus: '0.5'memory: 512Mx-deployment-notes: "This service is critical for production and should always have at least one replica running."
在這個例子中,x-custom-labels
和x-deployment-notes
都是擴展字段。前者可能被某個自定義腳本用于給服務添加特定標簽,后者則可能是對部署過程的一些額外說明或注意事項。
引用配置
version: '3.8'x-common-env: &common-env # 定義擴展字段(錨點)TZ: Asia/ShanghaiLANG: en_US.UTF-8services:web:image: nginxenvironment:<<: *common-env # 引用擴展字段NGINX_PORT: 8080db:image: postgresenvironment:<<: *common-envPOSTGRES_PASSWORD: example
使用 x-
前綴定義自定義字段:
x-custom:foo: barservices:web:image: nginxx-custom: ${x-custom}
實際應用場景
- 場景1:統一網絡配置
x-network: &networkaliases:- appipv4_address: 172.20.0.100services:frontend:networks:app_net: *networknetworks:app_net:driver: bridge
- 場景2:多環境變量管理
x-env: &env- .env- .env.${DEPLOY_ENV:-development}services:app:env_file: *env
- 場景3:CI/CD 集成
x-gitlab:variables:DOCKER_DRIVER: overlay2only:- master- tagsservices:runner:image: gitlab/gitlab-runner
- 文檔示例
x-myapp-docs: # 文檔示例description: |此擴展字段用于定義所有服務的公共健康檢查配置會被各服務通過YAML錨點引用
其它
# 1、查看擴展字段?
docker-compose config | grep x-# 2、Kubernetes 使用 annotations(注解)實現類似功能
metadata:annotations:mycompany.com/description: "自定義描述"
1.5.4、變量與環境替換
在Docker Compose配置文件中,變量與環境替換是一種允許你通過外部變量或環境變量動態地設置配置值的方法。這種方法極大地增強了配置文件的靈活性和可重用性,使得你可以輕松地在不同的環境中(如開發、測試、生產)使用同一份配置文件,只需調整相應的環境變量即可。
變量與環境替換的作用
- 提高配置文件的靈活性:允許根據不同的運行環境定制化服務配置,而無需修改Docker Compose文件本身。
- 保護敏感信息:避免將密碼、API密鑰等敏感信息直接寫入配置文件中,而是通過環境變量提供。
- 簡化多環境部署:可以在不同環境下復用同一個Compose文件,僅需改變環境變量的值。
使用方法
1. 使用環境變量
在docker-compose.yml
文件中,可以通過${VARIABLE}
的形式引用環境變量。例如:
version: '3.8'
services:db:image: "postgres:${POSTGRES_VERSION}"environment:- POSTGRES_USER=${POSTGRES_USER}- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
# 在這個例子中,POSTGRES_VERSION, POSTGRES_USER, 和 POSTGRES_PASSWORD都是從環境變量中讀取的值。# 嚴格模式變量
environment:API_KEY: ${API_KEY?err} # 未設置時報錯"err"
2.設置默認值
你還可以為環境變量指定一個默認值,以防它們未被定義。語法如下:${VARIABLE:default_value}
。例如:
version: '3.8'
services:web:build: .ports:- "${WEB_PORT:80}:${WEB_PORT:80}"
# 如果WEB_PORT環境變量未定義,則會使用默認端口80。
3. 使用.env
文件
通常,環境變量會被放置在一個名為.env
的文件中,該文件應該位于與docker-compose.yml
相同的目錄下。Docker Compose會自動加載這個文件中的變量。例如,你的.env
文件可能看起來像這樣:
POSTGRES_VERSION=13
POSTGRES_USER=myuser
POSTGRES_PASSWORD=mypassword
然后,在docker-compose.yml
中可以直接引用這些變量,而不需要額外的操作。
高級用法
# 1. 多環境配置
docker-compose --env-file .env.prod up # 命令行指定不同環境文件# 2、復合變量
environment:DB_URL: "postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}"# 3、Shell 命令結果
environment:BUILD_NUMBER: $(git rev-parse --short HEAD) # 注入Git提交哈希
實際應用示例
# 生產環境配置
# .env.prod 文件:
APP_ENV=production
DB_PASSWORD=secure123!
# docker-compose.yml 文件:
services:app:image: myapp:${APP_ENV:-development}environment:NODE_ENV: ${APP_ENV}DATABASE_URL: "mysql://user:${DB_PASSWORD}@db:3306/app"# 多階段構建
# docker-compose.yml 文件:
services:builder:image: builder:${BUILD_TAG:-latest}environment:- NPM_TOKEN=${NPM_TOKEN} # 從主機環境注入
變量加載順序
Docker Compose 按以下順序加載變量(后面的覆蓋前面的):
.env
文件(自動加載)- 主機環境變量
--env-file
指定的文件environment
部分直接定義的值
最佳實踐
# 1、敏感信息管理:
# 從保密管理工具注入
export DB_PASSWORD=$(vault read -field=password secret/db)
docker-compose up# 2、環境文件組織:
/config.env.dev.env.test.env.prod
docker-compose.yml# 3、文檔化變量:
x-env-docs:required:- DB_PASSWORD: 數據庫密碼optional:- LOG_LEVEL: 日志級別(default=info)
其它
# 1、查看最終替換后的配置?
docker-compose config# 2、變量未設置會怎樣
${VAR}:空字符串
${VAR:-default}:使用默認值
${VAR?error}:顯示錯誤信息并退出# 3、如何在容器內訪問這些變量?
# 在容器內執行
echo $LOG_LEVEL
2、其它指令
2.1、logging
服務的日志記錄配置。
driver:指定服務容器的日志記錄驅動程序,默認值為json-file。有以下三個選項
driver: "json-file"
driver: "syslog"
driver: "none"
2.2、deploy
指定與服務的部署和運行有關的配置。只在 swarm 模式下才會有用。
version: "3.7"
services:redis:image: redis:alpinedeploy:mode:replicatedreplicas: 6endpoint_mode: dnsrrlabels: description: "This redis service label"resources:limits:cpus: '0.50'memory: 50Mreservations:cpus: '0.25'memory: 20Mrestart_policy:condition: on-failuredelay: 5smax_attempts: 3window: 120s
詳細可以參考 官方文檔
或者 https://www.runoob.com/docker/docker-compose.html
介紹。
3、總結
3.1、environment指令
environment
是 Docker Compose 文件中用于設置容器環境變量的配置項,它允許你向容器內部傳遞配置參數和運行時設置。
這些環境變量可以用來配置服務的行為、連接字符串、認證信息等,它們對容器內的應用程序來說就像是操作系統的環境變量一樣。
基本概念
環境變量在容器中的作用:
- 配置應用程序:數據庫連接字符串、API密鑰等
- 控制程序行為:設置開發/生產環境模式
- 傳遞敏感信息:密碼、訪問令牌(但要注意安全性)
基本語法
1. 直接鍵值對形式(推薦)
services:web:image: nginxenvironment:NGINX_PORT: 8080DEBUG: "true"
2. 數組形式
services:web:image: nginxenvironment:- NGINX_PORT=8080- DEBUG=true
高級用法
1. 使用變量擴展
services:web:image: nginxenvironment:HOSTNAME: ${HOSTNAME} # 使用宿主機的環境變量VERSION: ${VERSION:-1.0} # 默認值
2. 從文件加載(適合敏感信息)
services:db:image: postgresenv_file:- .env # 從文件加載環境變量- db.env
3. 多環境配置
services:app:image: myappenvironment:- NODE_ENV=${APP_ENV:-development}- API_URL=${API_URL:-http://localhost:3000}
實際應用示例(常用)
1. 數據庫配置
services:mysql:image: mysql:8.0environment:MYSQL_ROOT_PASSWORD: my-secret-pwMYSQL_DATABASE: app_dbMYSQL_USER: app_userMYSQL_PASSWORD: user_password
Tips:
意思就是,在啟動初始化數據庫時候,設置 root 的密碼,和 創建一個 app_db 數據庫,和 app_user 用戶及對應的密碼。
如果沒有持久化數據庫,重啟容器后,之前的數據庫信息會丟失;如果持久化數據庫了,則也就是存在相應的文件,無論怎么重啟數據庫,一開始初始化數據庫的信息都還在。
2. 應用配置
services:app:build: .environment:RAILS_ENV: productionDATABASE_URL: postgres://user:pass@db:5432/app_prod REDIS_URL: redis://redis:6379/1
這里的 db
是我們定義的容器,因為在 Docker 網絡內部,服務名稱(mysql)會自動解析為容器的IP地址。
Tips:
這是給我們自己的 app 服務定于環境信息,就是說 可以在 app 項目代碼里面使用這些信息。
如果是 python:
# Python 示例 import os db_url = os.getenv("DATABASE_URL") # 讀取環境變量 env = os.getenv('DEBUG') # 讀取開發環境變量
如果是 javascript:
// Node.js 示例 const dbUrl = process.env.DATABASE_URL; // 讀取環境變量 const env = process.env.DEBUG // 讀取開發環境變量
3. 微服務配置
services:auth_service:image: auth-serviceenvironment:JWT_SECRET: ${JWT_SECRET}TOKEN_EXPIRY: 3600api_gateway:image: api-gatewayenvironment:AUTH_SERVICE_URL: http://auth:3000LOG_LEVEL: debug
安全最佳實踐
1.敏感信息處理:
environment:DB_PASSWORD: ${DB_PASSWORD} # 從宿主環境讀取
然后運行時傳入:
DB_PASSWORD=secret docker-compose up
2.使用 secrets(生產環境推薦):
services:db:image: postgressecrets:- db_password
secrets:db_password:file: ./db_password.txt
3.不要硬編碼密碼:
environment:DB_PASSWORD: "123456" # 直接寫在文件中不安全
調試技巧
-
查看容器的環境變量:
docker exec -it <container> env
-
檢查變量是否生效:
docker-compose config # 查看最終解析的配置
-
使用
--env-file
覆蓋:docker-compose --env-file .env.prod up
3.2、command 指令
command
是 Docker Compose 文件中用于覆蓋容器默認啟動命令的配置項,它允許你自定義容器啟動時執行的命令。
基本概念
當你在 Docker Compose 文件中使用 command
時,它會:
- 覆蓋 Docker 鏡像中定義的默認
CMD
指令 - 替換 容器啟動時運行的命令
- 不影響
ENTRYPOINT
(除非使用 shell 格式)
基本用法
1. 字符串格式
services:web:image: nginxcommand: nginx -g "daemon off;"
2. 列表格式(推薦)
services:web:image: nginxcommand: ["nginx", "-g", "daemon off;"]
與 Dockerfile 的關系
Dockerfile 指令 | 是否可被覆蓋 | 覆蓋方式 |
---|---|---|
ENTRYPOINT | 是 | entrypoint 配置項 |
CMD | 是 | command 配置項 |
實際應用場景
1. 修改默認參數
services:redis:image: rediscommand: redis-server --appendonly yes
2. 運行不同的可執行文件
services:node:image: node:14command: npm start
3. 調試容器
services:web:image: myappcommand: sh -c "while true; do echo 'Debugging...'; sleep 5; done"
3.3、entrypoint指令
entrypoint
指令用于覆蓋 Dockerfile 中定義的默認入口點(ENTRYPOINT)。它允許你在啟動容器時指定一個自定義的命令或腳本作為容器的第一個進程。通過這種方式,你可以改變容器的行為,使其執行不同的任務或初始化步驟。
作用
- 改變容器的默認行為:通過
entrypoint
,你可以讓容器運行不同于其設計初衷的應用程序或腳本。 - 簡化命令傳遞:與
CMD
不同,entrypoint
設置的是固定的執行命令,而CMD
可以被 docker run 命令行參數覆蓋。通常,entrypoint
定義了可執行文件,而CMD
提供該可執行文件的默認參數。 - 預處理和環境設置:可以用來運行一些初始化腳本或進行必要的環境配置,然后再啟動主應用程序。
- 容器角色:區分可執行容器(如CLI工具)與服務容器(如Web服務器)
使用方法
entrypoint
可以接受兩種形式的值:字符串(shell 形式)或數組(exec 形式)。推薦使用數組形式,因為它避免了 shell 的額外處理(如變量替換等),提供了更精確的控制。
1. 字符串格式(自動包裝為 /bin/sh -c
)
services:myapp:entrypoint: /app/start.sh --debugentrypoint: "/bin/echo Hello, world"
2. 列表格式(推薦,直接執行)
services:web:build: .entrypoint: /docker-entrypoint.sh # 初始化腳本command: ["nginx", "-g", "daemon off;"]redis:image: redisentrypoint: ["redis-server", "--appendonly", "yes"] # 覆蓋默認入口點myapp:entrypoint:- /app/start.sh- "--debug"entrypoint: ["/bin/echo", "Hello, world"]debug:image: nodeentrypoint: ["sleep"] # 調試容器command: ["infinity"] # 保持容器運行
3.結合 CMD 使用
entrypoint 和 cmd 經常一起使用。entrypoint 定義了要執行的命令,而 cmd 提供了該命令的默認參數。如果只定義了 entrypoint 而沒有 cmd,則 entrypoint 后面不需要參數;如果有 cmd,則它的值會被作為 entrypoint 命令的參數。
version: '3.8'
services:myservice:image: myimageentrypoint: ["/bin/echo"]cmd: ["Hello, world"]
這里,容器啟動時將執行 /bin/echo "Hello, world"
。
實際應用案例
設你有一個基于 Nginx 的服務,并希望在容器啟動前進行一些檢查或配置調整,可以通過 entrypoint
來實現:
version: '3.8'
services:web:image: nginxentrypoint: ["/docker-entrypoint.sh"]cmd: ["nginx", "-g", "daemon off;"]
在這個例子中,/docker-entrypoint.sh
是一個自定義腳本,它可能包含了對環境變量的檢查、日志清理等操作,之后再調用 nginx -g 'daemon off;'
來啟動 Nginx 服務器。
高級用法
1. 多命令組合
entrypoint:- sh- -c- |echo "Initializing..."exec "$@"- placeholder # 會被command替換
command: ["npm", "start"]
2. 環境變量擴展
entrypoint:- sh- -c- 'exec $$0 $$@' # 使用shell變量- /app/main.sh
3. 與用戶權限結合
entrypoint:- gosu- "1000:1000"- "/app/start.sh"
調試技巧
# 1、查看最終命令:
docker inspect --format='{{json .Config.Entrypoint}}' <container>
# 2、臨時覆蓋入口點:
docker-compose run --entrypoint bash myapp
# 3、日志檢查:
docker-compose logs --tail=100 myapp
最佳實踐
1、生產環境推薦:
entrypoint:- /docker-entrypoint.sh # 封裝初始化邏輯
command:- nginx- -g- daemon off;
2、開發環境調試:
entrypoint: ["sleep", "infinity"] # 保持容器運行
3、多階段初始化:
# Dockerfile
COPY entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]# docker-compose.yml
command: ["--debug"] # 作為參數傳給entrypoint.sh
Tips:
YAML 多行字符串的標記符號的使用。
entrypoint:- sh- -c- |echo "Initializing..."exec "$@"- placeholder
這里的 |
表示:
- 保留換行符:豎線后的內容會按原樣保留所有換行和縮進
- 多行文本塊:允許在單個 YAML 字段中編寫多行命令或腳本
- 末尾無換行:文本塊最后一行如果沒有空行,則不會添加額外換行符
對比其他 YAML 字符串標記
符號 | 名稱 | 特點 | 適用場景 | |
---|---|---|---|---|
` | ` | Literal Block | 保留所有換行和縮進 | 腳本、配置文件 |
> | Folded Block | 折疊換行為空格 | 長段落文本 | |
` | -` | Literal+Strip | 保留換行但刪除末尾空行 | 嚴格控制的腳本 |
>- | Folded+Strip | 折疊換行并刪除末尾空行 | 緊湊文本 |
實際應用示例
1. 多行腳本(推薦用 |
)
command: |/bin/sh -c 'echo "Starting app..."exec node server.js'
2. 長命令折疊(用 >
)
description: >This is a very long descriptionthat will be folded into a singleline when parsed.
3. 嚴格控制的腳本(用 |-
)
entrypoint: |-#!/bin/shset -eexec "$@"
注意
# 1、縮進規則:
- | # 正確縮進Line 1Line 2
- | # 錯誤!縮進不足Line 1Line 2# 2、特殊字符轉義:
- |echo "Hello \"World\"" # 需要轉義引號# 3、與 JSON 的兼容性:
// 等效JSON表示
{"command": "line1\nline2\n"}
調試技巧
# 1、驗證 YAML 解析:
python -c 'import yaml, sys; print(yaml.safe_load(sys.stdin))' < docker-compose.yml# 2、查看最終命令:
docker-compose config | grep -A 5 'entrypoint:'
4、常用設置
4.1 MySql 數據庫
command: ['mysqld', # 主命令:啟動MySQL服務器'--innodb-buffer-pool-size=80M', # 設置InnoDB緩沖池大小為80MB'--character-set-server=utf8mb4', # 設置默認字符集為utf8mb4'--character-set-server=utf8mb4','--collation-server=utf8mb4_unicode_ci', # 設置默認排序規則'--collation-server=utf8mb4_general_ci','--default-time-zone=+8:00', # 設置默認時區為東八區(北京時間)'--explicit_defaults_for_timestamp=true','--lower-case-table-names=1', # 設置表名大小寫不敏感(值為1)# 將mysql8.0默認密碼策略 修改為 原先 策略 (mysql8.0對其默認策略做了更改 會導致密碼無法匹配)'--default-authentication-plugin=mysql_native_password'
]
# 注意:上面設置,根據情況選擇,一定不要全部寫上
各參數詳細說明:
-
mysqld
MySQL 服務器的可執行文件名,啟動 MySQL 服務的主命令
-
--innodb-buffer-pool-size=80M
設置 InnoDB 存儲引擎的緩沖池大小為 80MB;這是 MySQL 最重要的性能參數之一,影響緩存表數據和索引的內存大小;適用于內存受限的環境(如小規格容器);通常建議設為可用內存的50-70%;
-
--character-set-server=utf8mb4
設置服務器默認字符集為 utf8mb4,支持完整的 Unicode 字符(包括emoji表情),替代舊的 utf8 編碼(只支持最多3字節字符)
-
--collation-server=utf8mb4_unicode_ci
設置默認排序規則為 utf8mb4_unicode_ci;影響字符串比較和排序行為;
ci
表示大小寫不敏感(case insensitive) -
--default-time-zone=+8:00
設置數據庫默認時區為 UTC+8(北京時間),影響 TIMESTAMP 類型字段的顯示和存儲,確保應用和數據庫時區一致
-
--lower-case-table-names=1
設置表名大小寫不敏感(值為1);Linux系統上默認區分大小寫,設為1使行為與Windows一致,避免因大小寫問題導致的查詢錯誤
5、Docker Compose 安裝
Linux 上我們可以從 Github 上下載它的二進制包來使用,最新發行的版本地址:https://github.com/docker/compose/releases。
直接下載需要的版本即可,比如:docker-compose-linux-x86_64
然后修改名稱:mv docker-compose-linux-x86_64 docker-compose
我們放在 /usr/local/bin 目錄中。
將可執行權限應用于二進制文件:chmod +x /usr/local/bin/docker-compose
創建軟鏈:ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
測試是否安裝成功:
$ docker-compose version
docker-compose version 1.24.1, build 4667896b
6、Docker Compose 常用服務例子
6.1、Java服務
version: "3.8"
services: java-api-server: container_name: my-java-server-nameimage: openjdk:8-jdkrestart: alwaysprivileged: trueports:- "8080:8080"volumes:- ./app:/home/data # 工作目錄,這里是存放我的jar包- ./files:/home/file # 附件目錄,上傳我的附件目錄working_dir: /home/datadepends_on:- redisenvironment:TZ: Asia/Shanghaicommand: java -jar app.jar
6.2、Redis 服務
version: "3.8"
services: redis:container_name: redisimage: redis:7.0.0restart: alwaysprivileged: trueports:- "6379:6379"volumes:- ./redis:/datacommand: redis-server redis.conf# 工作目錄和數據目錄默認都是 /data# 此處沒寫工作目錄,默認的工作目錄是/data,所以上述的 redis.conf 也是在 /data 目錄下。
redis.conf
配置文件:
# 配置密碼
requirepass 123456
# 控制當后臺持久化(BGSAVE)失敗時 Redis 是否拒絕寫入操作,默認yes,拒絕寫入直到下一次成功備份
stop-writes-on-bgsave-error no
6.3、MySql 服務
version: "3.8"
services: mysql:container_name: mysqlimage: mysql:8.0.32restart: alwaysprivileged: trueports:- "3306:3306"volumes:- ./mysql/conf:/etc/mysql/conf.d- ./mysql/logs:/var/log- ./mysql/data:/var/lib/mysqlenvironment:TZ: Asia/ShanghaiMYSQL_ROOT_PASSWORD: xxxxx
./mysql/conf/my.conf
文件參考:
[client]
user="root"
password="123456"
port=3306
default-character-set=utf8mb4[mysql]
default-character-set=utf8mb4 # 設置mysql客戶端默認字符集[mysqld]
port=3306
max_connections=1000
max_connect_errors=10 # 允許連接失敗的次數。這是為了防止有人從該主機試圖攻擊數據庫系統
max_allowed_packet=512M # 允許最大數據包大小
default-storage-engine=INNODB # 創建新表時將使用的默認存儲引擎
interactive_timeout=1800 # MySQL連接閑置超過一定時間后(單位:秒)將會被強行關閉
wait_timeout=1800 # MySQL默認的wait_timeout 值為8個小時, interactive_timeout參數需要同時配置才能生效
# Metadata Lock最大時長(秒), 一般用于控制 alter操作的最大時長sine mysql5.6
# 執行 DML操作時除了增加innodb事務鎖外還增加Metadata Lock,其他alter(DDL)session將阻塞
lock_wait_timeout=3600
# 設置分組模式
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
init_connect='SET collation_connection = utf8mb4_general_ci' # 設置全局聚合方式
init_connect='SET NAMES utf8mb4'
authentication_policy=mysql_native_password # 設置密碼驗證規則
character-set-server=utf8mb4 # 服務端使用的字符集默認為UTF8
collation-server=utf8mb4_general_ci
default-time-zone='+08:00' # 設置默認時區
activate_all_roles_on_login=ON # 設置開啟默認角色
# plugin-load-add=validate_password.so # 配置密碼復雜度策略
# validate-password=FORCE_PLUS_PERMANENT
# validate_password_length=8
# validate_password_policy=MEDIUM
# validate_password_check_user_name=ON
# default_password_lifetime=3 # 配置密碼過期策略
# password_history=6
# password_reuse_interval=365
# plugin-load-add=connection_control.so # 配置登錄失敗次數限制
# connection-control=FORCE_PLUS_PERMANENT
# connection-control-failed-login-attempts=FORCE_PLUS_PERMANENT
# connection-control-failed-connections-threshold=5
# connection-control-min-connection-delay=60000
# require_secure_transport=ON # 使用SSL加密連接[mysqldump]
# user="root"
# password="123456"
6.4、Nginx 服務
version: "3.8"
services: nginx:container_name: nginximage: nginx:latestrestart: alwaysprivileged: trueports:- "80:80"volumes:- ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf- ./nginx/log:/var/log/nginx- ./nginx/html:/usr/share/nginx/html- ./files:/home/data/files # 靜態資源代理
完畢。