###### 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)