docker-compose 是 Docker 官方的开源项目,使用 python 编写,实现上调用了Docker 服务的 API 进行容器管理及编排,其官方定义为定义和运行多个 Docker 容器的应用。
docker-compose 中有两个非常重要的概念:
• 服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
• 项目( project ):由一组关联的应用容器组成的一个完整业务单元,在 dockercompose.yml 文件中定义, 整个 docker-compose.yml 定义一个项目。
Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周
期管理。通过 compose 可以方便的管理多个服务。
Docker 是一个轻量化的应用程序, Docker 官方推荐每个 Docker 容器中只运行一
个进程。
• 如果一个应用需要涉及到 MySQL、 nginx 等环境, 那么我们需要分别为应用、数
据库和 nginx 创建单独的 docker 容器,然后分别启动容器。
• 想象一下,当我们构建好 Docker 之后,每次启动应用,都至少需要 docker run
三次, 或者写一些脚本来实现, 这样会比较繁琐。
• 另外,这些 docker 容器都是分散独立的,也不方便镜像管理。那既然这些 docker
容器 都是为了同一个应用服务,我们就应该把它们放到一起,这就引出了dockercompose 来解决这类型的问题。
目前官方支持三个大版本, 即 Version 1、 Version 2 及 Version 3, 其中 Version 1 已
经被废弃掉了。当前最新的版本是 3.8 。官方文档,还有compose文件命令
文件基本结构和常见命令
version: "3.8" # 定义版本, 表示当前使用的 docker-compose 语法的版本
services: # 服务,可以存在多个
servicename: # 服务名字,它也是内部 bridge 网络可以使用的 DNS name,
如果不是集群模式相当于 docker run 的时候指定的一个名称,
#集群(Swarm)模式是多个容器的逻辑抽象
image: # 必选,镜像的名字
command: # 可选,如果设置,则会覆盖默认镜像里的 CMD 命令
environment: # 可选,等价于 docker container run 里的 --env 选项
设置环境变量
volumes: # 可选,等价于 docker container run 里的 -v 选项 绑定数据
卷
networks: # 可选,等价于 docker container run 里的 --network 选项
指定网络
ports: # 可选,等价于 docker container run 里的 -p 选项指定端口映
射
expose: # 可选,指定容器暴露的端口
build: #构建目录
depends_on: #服务依赖配置
env_file: #环境变量文件
servicename2:
image:
command:
networks:
ports:
servicename3:
#...
volumes: # 可选,等价于 docker volume create
networks: # 可选,等价于 docker network create
指定容器运行的镜像。以下格式都可以:
image: redis
image: redis:5
image:
redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398
bc4b991aac7
image: library/redis
image: docker.io/library/redis
image: my_private.registry:5000/redis
覆盖容器启动的默认命令
command: ["nohup", "java", "-jar", "jarname", "&"]
command: nohup java -jar jarname &
version: '3.8'
services:
web:
image: nginx:latest
command: ["tail","-f","/etc/hosts"]
覆盖容器默认的 entrypoint。 Docker Compose中的entrypoint是一个可选的配置项,用于指定容器启动时要执行的命令或脚本。它可以在Dockerfile中定义,也可以在docker-compose.yml文件中定义。
services:
myservice:
entrypoint: ["command", "arg1", "arg2"]
其中,"command"是要执行的命令或脚本,"arg1"和"arg2"是命令的参数。
当容器启动时,entrypoint指定的命令或脚本会被执行。如果同时在docker-compose.yml文件中定义了command,那么entrypoint和command会被合并,最终执行的是entrypoint指定的命令或脚本,而command中的命令参数会作为entrypoint的参数。
也可以是以下格式
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-nonzts- 20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
示例
version: '3.8'
services:
web:
image: nginx:latest
entrypoint:
- tail
- -f
- /etc/os-release
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以
确保 YML 解析器不会将其转换为 True 或 False
#map 语法
environment:
RACK_ENV: development
SHOW: "true"
USER_INPUT:
#数组语法
environment:
- RACK_ENV=development
- SHOW=true
- USER_INPUT
示例
version: '3.8'
services:
web:
image: nginx:latest
environment:
TEST: 1
指定容器运行的网络
version: '3.8'
services:
web:
image: nginx:latest
environment:
TEST: 1
# 绑定网络
networks:
- mywebnet1
- mywebnet2
# 创建网络
networks:
mywebnet1:
mywebnet2:
配置网络驱动和子网信息
services:
frontend:
image: awesome/webapp
networks:
front-tier:
ipv4_address: 172.16.238.10
networks:
front-tier:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
将主机的数据卷或者文件挂载到容器里
version: '3.8'
services:
web:
image: nginx:latest
volumes:
- /data/maxhou/vol1:/usr/share/nginx/html
下面这段Docker Compose文件定义了一个服务(service)和一个卷(volume)。
服务部分:
卷部分:
这段Docker Compose文件的意思是创建一个名为"backend"的服务,使用"awesome/backend"镜像,并将两个卷与该服务进行关联。
#完整语法
services:
backend:
image: awesome/backend
volumes:
- type: volume
#命名卷
source: db-data
target: /data
volume:
nocopy: true
#绑定卷
- type: bind
source: /var/run/postgres/postgres.sock
target: /var/run/postgres/postgres.sock
# 创建卷
volumes:
db-data:
指定端口映射。
version: '3.8'
services:
web:
image: nginx:latest
ports:
- 8080:80
以下格式也可以
#完整语法
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
#短语法
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
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数
expose:
- "3000"
- "8000"
设置依赖关系。
• docker compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和
redis ,才会启动 web。
• docker compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,
docker compose up web 还将创建并启动 db 和 redis。
• docker compose stop :按依赖关系顺序停止服务。在以下示例中, web 在 db 和
redis 之前停止
这段Docker Compose文件的意思是创建了两个服务:web和mysql。web服务依赖于mysql服务,并且只有当mysql服务健康时,web服务才会启动。
mysql服务部分:
version: '3.8'
services:
web:
image: nginx:latest
depends_on:
mysql:
condition: service_healthy
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: root
healthcheck:
test: mysql -uroot -proot -e 'show databases;'
interval: 10s
timeout: 5s
retries: 10
从文件添加环境变量。可以是单个值或列表的多个值
version: '3.8'
services:
web:
image: nginx:latest
environment:
TEST: 1
env_file:
- ./commenv
- ./webenv
[root@aliyun docker-compose]# cat compose9/commenv
TEST2=2
TEST_2=2.2
命令 | 功能 | |
---|---|---|
docker compose build | 构建服务 | |
docker compose config | 规范的格式来显示服务配置 | |
docker compose cp | 在本地系统和服务容器直接拷贝文件 | |
docker compose create | 创建服务的容器 | |
docker compose down | 停止所有容器,并删除容器 | |
docker compose events | 从服务器获取实时事件 | |
docker compose exec | 在容器中执行命令 | |
docker compose images | 列出所有容器使用的镜像 | |
ocker compose kill | 强制停止服务的容器 | |
docker compose logs | 显示日志 | |
docker compose ls | 显示所有项目 | |
docker compose pause | 暂停服务 | |
docker compose port | 列出所有的端口映射 | |
docker compose ps | 该命令可以列出项目中目前的所有容器 | |
docker compose pull | 拉取服务镜像 | |
docker compose push | 推送服务镜像 | |
docker compose restart | 重启或者重启某个服务 | |
docker compose rm | 删除服务停止的容器 | |
docker compose run | 在指定服务容器上执行相关的命令 | |
docker compose start | 启动当前停止的某个容器 | |
docker compose top | 显示运行的进程 | |
docker compose unpause | 恢复服务 | |
docker compose up | up 命令会构建,(重新)创建,启动,链接一个服务相关的容器 | |
docker compose version | 查看版本 |
对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的
服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服
务都会受到命令影响。
docker-compose 命令的基本的使用格式为
docker compose [OPTIONS] COMMAND [ARGS...]
该命令的作用十分强大,它会尝试自动完成包括构建镜像、(重新)创建服务、启动服
务并关联服务相关容器的一系列操作,可以直接通过该命令来启动一个项目。
docker compose up [options] [SERVICE...]
-d 在后台运行服务容器, 推荐在生产环境下使用该选项
• --force-recreate 强制重新创建容器,不能与 --no-recreate 同时使用
• --no-recreate 如果容器已经存在了,则不重新创建,不能与 --forcerecreate 同时使用
停止所有容器,并删除容器和网络
docker compose down [options] [SERVICE...]
该命令可以在指定服务容器上执行相关的命令
# 例如:启动一个 ubuntu 服务容器,并执行 ping docker.com 命令
# docker compose run ubuntu ping docker.com
docker compose run [options] SERVICE [COMMAND] [ARGS...]
-d 后台运行容器
• --name NAME 为容器指定一个名字
• --entrypoint CMD 覆盖默认的容器启动指令
• -e KEY=VAL 设置环境变量值,可多次使用选项来设置多个环境变量
• -u, --user=“” 指定运行容器的用户名或者 uid
• --rm 运行命令后自动删除容器
• -p, --publish=[] 映射容器端口到本地主机
version: "3.8"
services:
mysys:
image: java:8
ports:
- 6060:6060
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
command: nohup java -jar /app/oj_java-0.0.1-SNAPSHOT.jar &
volumes:
- ./app/:/app/
networks:
- myhellonet
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: "root"
networks:
- myhellonet
volumes:
- ./mysql/varlib/:/var/lib/mysql
- ./mysql/init/:/docker-entrypoint-initdb.d/
healthcheck:
test: mysql -uroot -proot -e "show databases;"
interval: 10s
timeout: 5s
retries: 10
redis:
image: redis:7
networks:
- myhellonet
command: redis-server --protected-mode no --bind 0.0.0.0
healthcheck:
test: redis-cli ping
interval: 10s
timeout: 5s
retries: 10
networks:
myhellonet:
这段Docker Compose文件定义了三个服务(services):mysys、mysql和redis,并创建了一个网络(network)myhellonet。
mysys服务部分:
mysql服务部分:
redis服务部分:
networks部分: