Docker Compose全解析:概念、安装、命令与文件指令解析
笔记哥 /
04-19 /
19点赞 /
0评论 /
613阅读
## 什么是Docker Compose
Docker Compose 是 Docker 的一个编排管理工具,它允许你使用一个 YAML 文件来配置应用程序的服务。通过这个文件,你可以定义多个容器如何通过网络相互连接,以及如何配置它们的环境变量、卷挂载、端口映射等。这使得在单个主机上运行复杂的多容器应用程序变得非常简单和直观。
Docker Compose主要解决了`docker run`指令以及`docker build`后需要手动运行docker run的问题。
## Docker Compose主要概念
- 服务(Services):在 Docker Compose 文件中,一个服务通常指的是一个容器。你可以定义多个服务,每个服务都运行一个或多个容器实例。例如,你的应用程序可能包含一个 Web 服务和一个数据库服务。
- 网络(Networks):Docker Compose 可以创建和管理 Docker 网络,以便服务之间可以相互通信。默认情况下,Docker Compose 会为每个服务创建一个网络,但你也可以定义跨多个服务的自定义网络。
- 卷(Volumes):卷是 Docker 中用于持久化数据的一种机制。在 Docker Compose 中,你可以定义卷,并将卷挂载到容器内的特定路径上,这样即使容器被删除,数据也不会丢失。
- 环境变量(Environment Variables):你可以为服务定义环境变量,这些变量可以在容器内部被读取和使用。这对于配置应用程序的设置非常有用。
- 依赖(Dependencies):你可以在 Docker Compose 文件中定义服务的依赖关系,确保在启动服务时按照正确的顺序进行。例如,你可能希望先启动数据库服务,然后再启动依赖于数据库的服务。
## 安装Docker Compose
Docker Compose项目地址:
安装环境信息
| IP | 系统 | 规格 |
| --- | --- | --- |
| 10.0.0.10 | Ubuntu22.04 | 2c4g |
**安装前置准备:需要安装Docker**
安装步骤:
```csharp
# 下载Docker Compose
[root@lb ~]# wget
[root@lb ~]# ll docker-compose-linux-x86_64
-rw-r--r-- 1 root root 73664588 Apr 19 14:42 docker-compose-linux-x86_64
# 移动至/usr/bin/docker-compose
[root@lb ~]# mv docker-compose-linux-x86_64 /usr/bin/docker-compose
# 授予权限
[root@lb ~]# chmod +x /usr/bin/docker-compose
[root@lb ~]# ll /usr/bin/docker-compose
-rwxr-xr-x 1 root root 73664588 Apr 19 14:42 /usr/bin/docker-compose*
# 检查
[root@lb ~]# docker-compose version
Docker Compose version v2.35.0
```
## Docker Compose常用命令
Docker Compose的命令非常多,下面列举几个常用的,后文遇到新的命令继续讲解
### 容器相关
- docker-compose up -d:相当于`docker run -d`,创建并后台运行容器
- docker-compose ps:查看容器运行情况,只有`-q`选项
- docker-compose down:删除容器,删除所有容器的所有内容(网络、数据卷)
- docker-compose start:启动容器
- docker-compose stop:容器关闭
- docker-compose restart:重启容器
- docker-compose top:查看容器进程信息
- docker-compose logs:查看容器日志
- docker-compose rm:删除容器
- docker-compose exec:进入容器
### 镜像相关
- docker-compose pull:拉取服务的镜像
- docker-compose push:推送服务的镜像
- docker-compose build:构建服务镜像
## Docker Compose文件中常用指令
官网文章:
Docker Compose文件是一个yaml文件,且运行docker-compose命令时,所在的目录下必须有一个`docker-compose.yaml`或者`compose.yaml`文件。
### services
Compose 文件必须将services设置为顶级元素,`services`指定运行容器的相关信息,可以理解成`docker run`指令的集合
示例:
```csharp
# docker-compose文件
[root@lb ~/services]# cat docker-compose.yaml
services:
# 服务名称
web:
image: nginx:latest
ports:
- "8080:80"
# 运行容器
[root@lb ~/services]# docker-compose up -d
[+] Running 1/1
✔ Container services-web-1 Started
# 查看运行的容器
[root@lb ~/services]# docker-compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
services-web-1 nginx:latest "/docker-entrypoint.…" web About a minute ago Up About a minute 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp
```
### image
指定容器运行时的基础镜像
### ports
指定容器运行时的端口号,可以写多个
### container\_name
指定容器的名字,没有`container_name`标签时,会以`services-[services_name]-[services_num]`为容器名称
示例:
```csharp
[root@lb ~/container_name]# cat docker-compose.yaml
services:
web:
image: nginx:latest
# 指定容器名称
container_name: nginx_1
ports:
- "8081:80"
[root@lb ~/container_name]# docker-compose up -d
[+] Running 2/2
✔ Network container_name_default Created 0.1s
✔ Container nginx_1 Started 0.2s
[root@lb ~/container_name]# docker-compose ps -a
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
nginx_1 nginx:latest "/docker-entrypoint.…" web 5 seconds ago Up 5 seconds 0.0.0.0:8081->80/tcp, [::]:8081->80/tcp
```
### build
运行Dockerfile,构建镜像使用,有几个子标签
#### context
指定Dockerfile所在的目录
#### dockerfile
指定Dockerfile的文件名,同`docker build -f`指令,该指令可以不写,默认是Dockerfile
示例:
```csharp
[root@lb ~/build]# cat compose.yaml
services:
zrlog:
container_name: zrlog
# build指令使用
build:
context: ./zrlog
dockerfile: Dockerfile
ports:
- "8082:8080"
# 构建镜像
[root@lb ~/build]# docker-compose build
Compose can now delegate builds to bake for better performance.
To do so, set COMPOSE_BAKE=true.
[+] Building 6.5s (9/9) FINISHED docker:default
=> [zrlog internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 409B 0.0s
=> [zrlog internal] load metadata for docker.io/library/tomcat:9.0.87-jdk8-corretto 6.3s
=> [zrlog internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [zrlog internal] load build context 0.1s
=> => transferring context: 10.80MB 0.1s
=> [zrlog 1/3] FROM docker.io/library/tomcat:9.0.87-jdk8-corretto@sha256:6928733a4f4c15d61c45a14b0197fe9a160f49f6f13b1b0b06310561cb320ef0
=> => writing image sha256:0d6bbaa1db8bf9d30e976c17f2991aca20e6b6e070be646b85240e1ec0ffdc71 0.0s
=> => naming to docker.io/library/build-zrlog 0.0s
=> [zrlog] resolving provenance for metadata file 0.0s
[+] Building 1/1
✔ zrlog Built 0.0s
# 启动镜像
[root@lb ~/build]# docker-compose up -d
[+] Running 2/2
✔ Network build_default Created 0.1s
✔ Container build-zrlog-1 Started
[root@lb ~/build]# docker-compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
zrlog build-zrlog "catalina.sh run" zrlog About a minute ago Up About a minute (healthy) 0.0.0.0:8082->8080/tcp, [::]:8082->8080/tcp
```
### environment
`docker run -e`选项,指定容器运行后的环境变量
示例:
```csharp
[root@lb ~/environment]# cat compose.yaml
services:
db:
image: mysql:5.7
container_name: mysql_db
ports:
- "3306:3306"
environment:
# 指定MySQL root的密码
- "MYSQL_ROOT_PASSWORD=root123"
# 指定创建一个zrlog的数据库
- "MYSQL_DATABASE=zrlog"
# 运行
[root@lb ~/environment]# docker-compose up -d
[+] Running 2/2
✔ Network environment_default Created 0.1s
✔ Container mysql_db Started
# check
[root@lb ~/environment]# docker-compose ps -a
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
mysql_db mysql:5.7 "docker-entrypoint.s…" db 14 seconds ago Up 14 seconds 0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp, 33060/tcp
```
### restart
指定容器的重启方式,和`docker run --restart`选项一致
重启方式:
- always:自动重启
- unless-stopped:只在容器关闭,停止的时候重启
- on-failure:只在失败的时候重启
示例:
```csharp
services:
db:
# 指定重启策略
restart: always
image: mysql:5.7
container_name: mysql_db
ports:
- "3306:3306"
environment:
# 指定MySQL root的密码
- "MYSQL_ROOT_PASSWORD=root123"
# 指定创建一个zrlog的数据库
- "MYSQL_DATABASE=zrlog"
```
### volumes
官网文章:
volumes指令在Compose文件中有两个作用,作为顶级元素时,volume会创建一个数据卷,作为子级元素时,会为容器挂载数据卷。
示例:
```csharp
[root@lb ~/volumes]# cat compose.yaml
services:
db:
# 指定重启策略
restart: always
image: mysql:5.7
container_name: mysql_db_1
ports:
- "3307:3306"
environment:
# 指定MySQL root的密码
- "MYSQL_ROOT_PASSWORD=root123"
# 指定创建一个zrlog的数据库
- "MYSQL_DATABASE=zrlog"
volumes:
- mysql_data:/var/lib/mysql
# 创建mysql_data的数据卷
volumes:
mysql_data:
# 启动容器
[root@lb ~/volumes]# docker-compose up -d
[+] Running 1/1
✔ Container mysql_db_1 Started # 检查 0.3s
[root@lb ~/volumes]# docker-compose ps -a
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
mysql_db_1 mysql:5.7 "docker-entrypoint.s…" db 4 seconds ago Up 4 seconds 33060/tcp, 0.0.0.0:3307->3306/tcp, [::]:3307->3306/tcp
# 检查数据卷
[root@lb ~/volumes]# docker inspect mysql_data
[
{
"CreatedAt": "2025-04-12T15:42:17+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql_data/_data",
"Name": "mysql_data",
"Options": null,
"Scope": "local"
}
]
```
#### 当需要挂载到本机宿主机时,仅使用次级元素的volumes即可
示例:
```csharp
services:
web:
image: nginx:latest
volumes:
- ./html:/usr/share/nginx/html
```
#### 可以使用外部存储卷
示例:
```csharp
services:
web:
image: nginx:latest
volumes:
- web_data:/usr/share/nginx/html
volumes:
web_data:
#external指定此卷已存在于平台上,并且其生命周期由应用程序之外的生命周期管理。如果卷不存在,Compose 将不会创建该卷并返回错误。
external: true
```
### healthcheck
`healthcheck`用于定义服务的健康检查机制。通过健康检查,可以确保容器在启动后能够正常运行,并且在容器不可用时自动重启或重新调度.
其子元素有:
- test:定义健康检查的命令。可以是一个命令或一个脚本。
- interval:两次健康检查之间的间隔时间(默认单位为秒)。
- timeout:单次健康检查的超时时间。
- retries:健康检查失败后重试的次数。
- start\_period:容器启动后开始健康检查的延迟时间。
示例:
```csharp
services:
web:
image: nginx:latest
ports:
- "80:80"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
```
### depends\_on
`depends_on`用于控制服务之间的启动顺序。它确保在启动某个服务之前,其依赖的服务已经启动。例如web服务依赖数据库服务,需要数据库服务先启动时可以使用depends\_on。
虽然`depends_on`确保了服务的启动顺序,但它不会等待服务完全启动后再启动依赖的服务,例如,数据库服务可能还在初始化过程中,而web服务已经启动了,这可能会导致web应用程序无法连接到数据库服务,这个时候需要使用`healthcheck`
`depends_on`只会影响容器的启动顺序,不会影响容器的停止顺序
示例:
```csharp
services:
web:
image: nginx:latest
ports:
- "80:80"
# 指定依赖db服务
depends_on:
db:
condition: service_healthy
db:
image: mysql:latest
environment:
- "MYSQL_ROOT_PASSWORD=root123"
# 健康检查
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
```
### links(在Docker Compose版本3以上已被废弃)
`links` 是一个用于定义服务之间网络连接的指令。它允许一个服务访问另一个服务的容器,并通过服务名称进行通信。虽然 links 在 Docker Compose 的早期版本中非常常用,但在 Docker Compose 版本 3 及以上中,`links` 已被废弃,推荐使用默认的网络功能来实现服务之间的通信。
links的作用:
- 建立网络连接:links 用于在服务之间建立网络连接,允许一个服务访问另一个服务的容器。
- 环境变量和 /etc/hosts:当使用 links 时,Docker 会自动设置环境变量和 /etc/hosts 条目,使得服务之间可以通过服务名称进行通信。
示例:
```csharp
[root@lb ~/links]# cat compose.yaml
services:
web1:
container_name: nginx1
image: nginx:latest
links:
- web2:nginx
ports:
- "81:80"
web2:
container_name: nginx2
image: nginx:latest
ports:
- "82:80"
# 运行容器
[root@lb ~/links]# docker-compose up -d
[+] Running 3/3
✔ Network links_default Created 0.1s
✔ Container nginx2 Started 0.4s
✔ Container nginx1 Started 0.6s
# 检查
[root@lb ~/links]# docker-compose ps -a
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
nginx1 nginx:latest "/docker-entrypoint.…" web1 13 seconds ago Up 11 seconds 0.0.0.0:81->80/tcp, [::]:81->80/tcp
nginx2 nginx:latest "/docker-entrypoint.…" web2 13 seconds ago Up 12 seconds 0.0.0.0:82->80/tcp, [::]:82->80/tcp
###### 测试,进入nginx1的容器内部
[root@lb ~/links]# docker exec -it nginx1 bash
# 查看hosts解析
root@12b2517e712e:/# cat /etc/hosts
127.0.0.1 localhost
...
# web2的hosts解析
172.24.0.3 12b2517e712e
root@12b2517e712e:/# curl
curl: try 'curl --help' or 'curl --manual' for more information
root@12b2517e712e:/# curl
# 网页内容