上篇回顧
設定檔格式 YAML
Docker太多文章介紹了, 小弟我K8S也沒那麼熟稔
就介紹自己熟的Compose吧
Docker的相關入門能參考
30 天與鯨魚先生做好朋友
30天與 Docker 做好朋友:跟鯨魚先生一同探索開發者的大平台(iT邦幫忙鐵人賽系列書)
Github
常常一個專案內, 主要的業務服務會有一些依賴的服務一起搭配, 進而完成工作.
常見的其他服務有Nginx
、DB(MySQL, Postgre...)
、NoSQL(Redis、Mongo...)
、SMTP
...etc
至於這compose需要什麼服務, 就看各業務服務需要哪些了.
利用DockerCompose來管理容器, 或者配置各容器需要掛載到哪個network、volume...,
都能透過開發者定義的docker-compose.yml文件, 來定義一組相關連的容器為一個Project.
所以上篇才介紹一下YAML
Docker-compose的圖, 也正好說明,
一隻章魚?魷魚?有好幾隻手, 每個觸手上管理著一個container, 任章魚把玩
其實只是管理便利性地差異,
Docker-compose還是要先安裝好Docker, 當然Compose也能來編譯原本寫好的Dockerfile
如果自己是喜歡寫Makefile或Shell快速管理的高手, 當然也是可以不需要Compose.
Compose默認管理的對象是Project
, 透過命令對Project中的容器進行生命週期管裡
以下只是範例, 並不真能跑, 因為我沒放web專案的代碼
version: "3"
services:
web:
ports:
- 80:80
environment:
PRODUCTION: 'true'
backgroundservice:
build:
context: ../
dockerfile: docker/CrawlerDockerfile
db:
image: mysql:8.0
ports:
- "3306:3306"
command: [
"--server-id=1",
"--default-authentication-plugin=mysql_native_password"
]
volumes:
- ./db.cnf:/etc/mysql/conf.d/mysqld.cnf
- ./sql:/docker-entrypoint-initdb.d
每個service都需要透過image
指令來指定image名稱與版本(如web和db)
又或者透過build
指令來編譯Dockfile, 建構出image(如backgroundservice)
context
args
指定Dockfile所在的文件位置, 可以是絕對位置或相對位置),
Compose會自動利用這路徑下的Dockfile來自動構建出image, 然後使用該image進行容器的設定
---
version: "3.9"
services:
webapp:
build: ./dir #直接指定路徑, 前提要dockfile檔名剛好是Dockerfile
...
---
version: "3.9"
services:
webapp:
build:
context: ./dir #透過context來指定路徑
dockerfile: Dockerfile-alternate #說明要執行編譯的Dockfile檔名
args: # 指定編譯image時, 所需要的arguments
buildno: 1
...
指定image名稱, 版本, 甚至能直接指定image ID(但我不推薦,, 沒閱讀性)
用來覆蓋容器啟動後默認執行的動作, 跟dockerfile的CMD
類似的
在推薦的書本裡Chap5也有提到
開放port給container連線, 但沒有映射到host上
expose:
- "3000"
- "8000"
將port綁定在host上, 然後就能在host的環境, 與容器做交互
當使用docker-compose up時, 依照依賴順序, 以範例來說會先啟動db和redis,再來啟動web
docker-compose stop時, 一樣反序的關閉容器.
Control startup and shutdown order in Compose但! 只是啟動順序, 不代表web被啟動完成時, db已經啟動完成.
以下是官網的說明, 就只有啟動, 並不會等待容器的狀態到Ready
However, for startup Compose does not wait until a container is “ready” (whatever that means for your particular application) - only until it’s running. There’s a good reason for this.
官網推薦的作法是在透過一隻wait-for-it.sh
,
在依賴方執行透過docker-compose的command
或直接寫在dockerfile的CMD
去執行;
vishnubob/wait-for-it
eficode/wait-for
或是被依賴方透過healthcheck
去執行CMD, DockerLibrary有提供一些服務的HealthCheck腳本
透過healthcheck的話, 請別用until-do-done,
透過命令提供的options: interval, timeout, start-period retries來做循環
直接執行一次成功回應exit 0, 失敗回應exit 1ps 這方法有版本限制問題
version: "3.9"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
docker-compose太多config options了, 大家能自己到官網學習
docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]
options:
docker-compose.yml
commands:
docker-compose build [options] [SERVICE...]
關於Docker desktop的替代方案之一的Podman, 也支持compose, 所以轉換上挺方便的
Docker-compose對於一個專案內有多個容器的需求時, 管理容器的生命週期以及設定檔的撰寫非常便利.
且由於是一個專案內要設定多個service, 所以上一篇學到的anchor&
和alias*
, 應該能在很多開源專案內的yml常看到.
雖然Docker漸漸地被冷漠?
但為了方便開發者與運維人員便利管理容器, 且Docker真的太夯,
基本替代方案出來, 還是兼容Dockerfile與Docker-compose.
相關說明能參考
30天分享那些年我怎麼理解 kubernetes 的運作
Dokcker-compose V2最近剛釋出,
V1是用Python開發的, V2則是用Go
使用指令上, V1如文章是docker-compose
, V2則是docker compose
詳情能看Compose Github連結