###### tags: `docker` <style> .warning { color: red; border: 2px solid black; border-radius: 5px; display: flex; align-items: center; padding: 5px 10px; } .warning::before { content:""; display: inline-block; background-size: 100% 100%; background-image: url(https://i.imgur.com/2XrjoMP.png); width: 25px; height: 25px; margin-right: 5px; } .text-bold { font-weight: bold; } .note { background-color: #fe6b00; display: flex; align-items: center; border: 2px solid black; border-radius: 5px; padding: 5px 10px; } .note::before { content:""; display: inline-block; background-size: 100% 100%; background-image: url(https://i.imgur.com/GLwjyJa.png); width: 25px; height: 25px; margin-right: 5px; } </style> # docker-compose 詳細說明 ```yaml services: your_container1: your_container2: volumns: networks: ``` ## Services - container相關設定 ### image ```yaml services: your_container1: image: your_image ``` - image選項用於指定該container要使用的image。 - 若有build選項,則image可不寫。 ### build ```yaml services: your_container1: build: ``` - container所使用的image相關設定 #### context (REQUIRED) ```yaml build: context: /path/to/your/dockerfile ``` ```yaml build: context: https://github.com/your-account/your-repo.git ``` - 用來指定包含建構該container的Dockerfile的相對或絕對路徑。可用git的url。 - 相對路徑是相對於docker-compose檔案 #### dockerfile ```yaml build: context: . dockerfile: your_dockerfile_name ``` - dockerfile選項不可使用相對路徑,必須先使用context指定包含該dockerfile的路徑。 #### args ```yaml build: context: . arg: YOUR_ARG1: asd YOUR_ARG2: qwe ``` - dockerfile ```dockerfile ARG YOUR_ARG1 ARG YOUR_ARG2 ``` - args選項可以設定dockerfile裡的ARG參數,如上述範例:dockerfile中的YOUR_ARG1與YOUR_ARG2皆在docker-compose檔裡設定為asd與qwe。 #### labels - 與dockerfile裡的LABEL使用方法一樣。 ### container_name ```yaml services: your_container1: container_name: custom_container ``` - container_name必須是唯一的,且須符合正規表達式`[a-zA-Z0-9][a-zA-Z0-9_.-]+` ### volumns - 指定外部的空間或已命名的volumn映射到container內的路徑。 #### 短語法 ```yaml volumes: - [SOURCE:]TARGET[:MODE] ``` - SOURCE: 可以是外部的路徑或是已命名的volume。 - TARGET: container內的路徑 - MODE: 預設是rw(read write),有ro(read only)和rw可選。 ```yaml services: your_container: #... volumes: # 只指定container的路徑,讓docker幫你建立volume。 - /var/lib/mysql # 指定外部的絕對路徑到container的絕對路徑。 - /opt/data:/var/lib/mysql # 使用相對路徑,相對於compose檔。 - ./cache:/tmp/cache # User-relative path - ~/configs:/etc/configs/:ro # 使用已命名的volume - datavolume:/var/lib/mysql #... ``` #### 長語法 - [待續](https://docs.docker.com/compose/compose-file/#volumes) ### env_file - 根據外部env檔來添加環境變數。 ```yaml services: my_container: #... env_file: .env #or env_file: - ./a.env - ./b.env #... ``` - 若填寫相對路徑,則是相對於compose檔的路徑 ### environment ```yaml services: my_container: #映射寫法 environment: RACK_ENV: development SHOW: "true" USER_INPUT: #list寫法 environment: - RACK_ENV=development - SHOW=true - USER_INPUT ``` - 支援映射或list寫法 <p class="note text-bold">若同時存在enviroment選項與env_file選項,則前者優先於後者。</p> ### networks ### depends_on - depend_on設定service之間啟動的依賴關係。 - 短語法 ```yaml services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres ``` - 上述範例 : - redis與db啟動之後再啟動web。 - web移除之後再移除redis與db。 - 長語法 ```yaml services: web: build: . depends_on: db: condition: service_healthy redis: condition: service_started redis: image: redis db: image: postgres ``` - 使用condition來設定依賴的service在特定狀態才啟動。 - 可選選項: - service_started: 等同於短語法的效果。 - service_healthy: 等到依賴的service的狀態為"healthy"(詳情見[healthcheck](#healthcheck))才啟動。 - service_completed_successfully: 等到依賴的service成功運行才啟動。 ### entrypoint ```yaml services: your_container1: entrypoint: command param1 param2 your_container2: entrypoint: ["executable" ,"param1" ,"param2"] your_container3: entrypoint: - executable - param1 - param2 ``` - 與dockerfile裡的ENTRYPOINT功能一樣 - 若dockerfile與docker-compose裡都有entrypoint,後者會覆蓋前者。 - 支援list寫法(your_container3的寫法),視為exec form。 ### command ```yaml services: your_container1: command: command param1 param2 your_container2: command: [ "executable", "param1", "param2"] your_container3: command: - executable - param1 - param2 ``` - 用法與dockerfile的CMD一樣 - 如果同時存在entrypoint和command時,commnad會作為entrypoint的參數。 ### ports - 將container的port對外開放 <p class="warning text-bold">不可與network_mode: host一起使用,否則將會抱錯。</p> #### 短語法 ```yaml services: your_container1: ports: - [HOST:]CONTAINER[/PROTOCOL] ``` - HOST: 外部的port。 - CONTAINER: container內的port。 - PROTOCOL: 所使用的網路協定,TCP或UDP。 >HOST與CONTAINER可以是1組ip或ip range。 - Ex: ```yaml services: your_container1: ports: - "3000" - "3000-3005" - "8000:8000" - "9090-9091:8080-8081" - "49100:22" - "127.0.0.1:8001:8001" - "127.0.0.1:5000-5010:5000-5010" - "6060:6060/udp" ``` #### 長語法 ```yaml services: your_container1: ports: - target: 80 host_ip: 127.0.0.1 published: 8080 protocol: tcp mode: host - target: 80 host_ip: 127.0.0.1 published: 8000-9000 protocol: tcp mode: host ``` - target: container內的port。 - host_ip: 外部的ip,預設值為0.0.0.0。 - published: 外部的port,可以是ip range。 - protocol: 預設值為"任何"。 - mode: `host` for publishing a host port on each node, or `ingress` for a port to be load balanced. ### healthcheck ```yaml services: your_container1: healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] interval: 1m30s timeout: 10s retries: 3 start_period: 40s ``` - 用法與dockerfile的HEALTHCHECK一樣。 - test: 可以為單個字串或list。若是list,第一個必須填 `NONE`、`CMD`、`CMD-SHELL`,若為字串,則視為`CMD-SHELL`。 - `CMD`: exec form - Ex: ```yaml test: ["CMD", "curl", "-f", "http://localhost"] ``` - `CMD-SHELL`: shell form - Ex: ```yaml test: ["CMD-SHELL", "curl -f http://localhost || exit 1"] test: curl -f https://localhost || exit 1 ``` - 若要停用healthcheck可使用`disable: true`選項,此選項等同於`test: ["NONE"]`。 ```yaml healthcheck: disable: true ``` ### network_mode ```yaml services: my_container: network_mode: "host" #or network_mode: "none" #or network_mode: "service:[service name]" ``` - 設定container的網路模式,有`none`、`host`、`service:{name}`可選。 - `none`: 停用所有網路活動。 - `host`: 使container與host共用網路,使得container可以訪問host。 - `service:{name}`: 使container只允許存取該service。 ### network ```yaml services: some-service: networks: - some-network - other-network ``` - 可使用在最上層networks元素中已命名的元素。 #### aliases ```yaml services: backend: image: awesome/backend networks: back-tier: aliases: - database admin: aliases: - mysql networks: back-tier: admin: ``` - aliases選項可設定該service在該網路中的別名,而其他同在該網路的service可用別名呼叫。 #### ipv4_address/ipv6_address ```yaml services: frontend: image: awesome/webapp networks: front-tier: ipv4_address: 172.16.238.10 ipv6_address: 2001:3984:3989::10 networks: front-tier: ipam: driver: default config: - subnet: "172.16.238.0/24" - subnet: "2001:3984:3989::/64" ``` - 使service在加入該網路使用固定ip。 <p class="note text-bold"> 必須在最上層networks元素中有設定ipam選項才可使用。 </p> ### expose ```yaml services: your_container1: expose: - "3000" - "8000" ``` - 將container內的port對同個compose內的container開放,並沒有對外開放。 ### logging [待續](https://docs.docker.com/compose/compose-file/#logging) ## Volumns ```yaml services: backend: image: awesome/database volumes: - db-data:/etc/data backup: image: backup-service volumes: - db-data:/var/lib/backup/data volumes: db-data: ``` - 管理已命名的volume。 ## Networks ```yaml services: frontend: image: awesome/webapp networks: - front-tier - back-tier networks: front-tier: back-tier: ``` - 上述範例為:建立front-tier與back-tier的網路,並且讓service frontend加入。 ### driver - driver選項有`host`、`bridge`、`overlay`、`macvlan `,差別可以看[這篇文章](https://ithelp.ithome.com.tw/articles/10242460)。 ### ipam - ip address manager的縮寫 ```yaml ipam: driver: default config: - subnet: 172.28.0.0/16 ip_range: 172.28.5.0/24 gateway: 172.28.5.254 aux_addresses: host1: 172.28.1.5 host2: 172.28.1.6 host3: 172.28.1.7 options: foo: bar baz: "0" ``` - driver: ipam的driver,預設是default。 - config: - subnet: 子網域 - gateway: 預設閘道 - ip_range: - options: - [待續](https://docs.docker.com/compose/compose-file/#ipam) ## Docker 常用語法 - docker images -a : 查詢所有 image - docker rmi [IMAGE_ID] : 刪除指定 image - docker ps -a : 查詢所有 container - docker rm [CONTAINER_ID] : 刪除指定 container # 參考文獻 [Docker Docs | Compose specification](https://docs.docker.com/compose/compose-file/#external_links)