一、Docker Compose 简介
Docker Compose是一种用于定义和运行多容器Docker应用程序的工具。通过一个 docker-compose.yml 文件,您可以配置应用程序需要的所有服务(例如-Web服务器、数据库、缓存等)并轻松管理它们。
Docker Compose 使用的三个步骤-
使用 Dockerfile 定义应用程序的环境。 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。 最后,执行 docker-compose up 命令来启动并运行整个应用程序。
二、docker-compose 常用命令
1、docker-compose up 命令 用法-
docker-compose up [options]功能- 创建并启动服务(容器)-如果服务尚未创建,docker-compose up -d 会根据 docker-compose.yml 文件中的定义创建并启动这些服务。 后台运行—d 参数表示“detached”模式,即以分离模式运行,服务会在后台运行,不会占用当前终端。 重新创建容器-如果服务已经存在且正在运行,docker-compose up -d 会先停止并删除现有的容器,然后重新创建并启动新的容器。 构建镜像-如果配置文件中指定了 build 指令,docker-compose up -d 会先构建所需的 Docker 镜像。 检查配置-在启动服务之前,docker-compose up -d 会检查并验证 docker-compose.yml 文件中的配置。 使用场景-
首次部署-当你第一次部署服务时,使用 docker-compose up -d 可以确保所有服务都按最新配置创建并启动。 更新服务-当你修改了 docker-compose.yml 文件中的配置或镜像,使用 docker-compose up -d 可以确保这些更改生效。 确保最新状态-无论服务是否已经存在,docker-compose up -d 都会确保服务是最新的状态。 用于部署一个 Compose 应用。
默认情况下该命令会读取名为 docker-compose.yml 或 docker-compose.yaml 的文件。
当然用户也可以使用 -f 指定其他文件名。通常情况下,会使用 -d 参数令应用在后台启动。
2、docker-compose down 命令 用法-
docker-compose down [options]功能-
docker-compose down -v 命令用于停止并移除使用 docker-compose.yml 文件定义的所有容器、网络、卷(通过 -v 参数指定的数据卷)以及默认的网络桥接。 使用 -v 参数会删除所有命名的数据卷。这可能会导致数据丢失,因此在执行前请确保已经做好了必要的备份。 使用场景-
适用于彻底清理环境,例如在开发过程中需要重置环境或者测试不同配置时。 完全重置环境-当你需要完全重置开发环境,确保没有任何遗留数据时,可以使用 docker-compose down -v。 测试环境清理-在自动化测试中,每次测试结束后使用 docker-compose down -v 可以确保环境干净,不受上次测试的影响。 部署前清理-在部署新版本应用之前,使用 docker-compose down -v 可以确保没有旧版本的残留数据。 选项-
—rmi
local-仅删除那些不带有 :(表示镜像标签)或 latest 标签的镜像(通常是构建时创建的镜像)。
-v 或 —volumes-移除所有为服务定义的卷(包括默认卷和命名卷)。 —rmi-all-等同于 —rmi all,删除所有服务的镜像。 -h, —help-显示帮助信息。 示例-
1)停止并移除容器、网络和默认网络
docker-compose down2)停止并移除容器、网络、卷以及镜像
docker-compose down --volumes --rmi all3)仅移除构建时创建的本地镜像
docker-compose down --rmi local4)指定配置文件
docker-compose -f my-compose-file.yml down注意事项-
使用 docker-compose down —volumes 会删除所有在 docker-compose.yml 文件中定义的卷,包括默认卷和命名卷。如果你不想删除这些卷,请不要使用这个选项。 删除镜像操作是不可逆的,请确保在删除镜像之前备份必要的数据。 如果你使用 Docker Compose 来管理多个环境(例如开发、测试和生产环境),请确保你在正确的环境中运行 docker-compose down 命令,以避免误删重要数据。 3、docker-compose stop 命令
docker-compose stop停止 Compose 应用相关的所有容器,但不会删除它们。
被停止的应用可以很容易地通过 docker-compose restart 命令重新启动。
docker-compose stop 命令用于停止通过 docker-compose.yml 文件定义并启动的所有容器。这个命令不会移除容器、网络或卷,它只是停止了容器的运行。
4、docker-compose start 命令
docker-compose startdocker-compose start 命令用于启动之前已经创建但已停止的容器。
5、docker-compose restart 命令
docker-compose restart重启已停止的 Compose 应用。
如果用户在停止该应用后对其进行了变更,那么变更的内容不会反映在重启后的应用中,这时需要重新部署应用使变更生效。
6、docker-compose ps 命令
docker-compose ps用于列出 Compose 应用中的各个容器。
输出内容包括当前状态、容器运行的命令以及网络端口。
7、docker-compose rm 命令 用于删除已停止的 Compose 应用。它会删除容器和网络,但是不会删除卷和镜像。
语法-
docker-compose rm [OPTIONS] [SERVICE...]选项-
-f, —file FILE-指定使用的 Compose 配置文件,默认为 docker-compose.yml。 -v, —volumes-删除容器的同时删除由 docker-compose.yml 文件定义的卷(如果它们存在并且是容器专用的)。 -a, —all-删除所有服务容器,而不仅仅是停止的容器。默认情况下,docker-compose rm 只删除停止的容器。 —rmi TYPE-删除镜像。这个选项会删除构建镜像时产生的中间镜像和构建缓存。TYPE 可以是 all(删除所有镜像)、local(只删除本地镜像)或 built(只删除通过 docker-compose 构建的镜像)。 -s, —stop-在删除容器之前先停止它们。这是默认行为,可以通过添加 —no-stop 标志来覆盖。 —no-stop-在删除容器之前不停止它们(通常与 -f 一起使用)。 示例-
1)删除所有停止的容器
docker-compose rm这个命令会删除所有在 docker-compose.yml 文件中定义且当前已停止的容器。
2)删除所有容器
docker-compose rm -a这个命令会删除所有在 docker-compose.yml 文件中定义的容器,无论它们是运行中的还是已停止的。
3)删除容器和卷
docker-compose rm -v这个命令会删除所有已停止的容器以及由 docker-compose.yml 文件定义的卷(如果它们存在并且是容器专用的)。
4)使用指定的 Compose 配置文件
docker-compose -f my-compose.yml rm这个命令会使用 my-compose.yml 文件来删除容器。
5)删除镜像
docker-compose rm --rmi local这个命令会删除所有通过 docker-compose 构建且在本地存在的镜像。
注意事项-
使用 docker-compose rm 命令时,请确保你确实想要删除这些容器,因为删除后的数据(除非已备份到卷中)将不可恢复。 如果容器正在运行,你需要先停止它们,或者使用 -s 或 —stop 选项来确保在删除之前先停止它们。 8、docker-compose logs 命令 docker-compose logs 命令用于查看 Docker Compose 应用中各个服务的日志。这个命令非常有用,因为它可以帮助你诊断问题或监视服务的行为。
基本用法-
docker-compose logs [options] [SERVICE...]SERVICE(可选)-指定要查看日志的服务名称。如果未指定,则显示所有服务的日志。
常用选项-
—follow, -f-实时跟踪日志输出,类似于 tail -f。 —tail, -t “all”-显示日志的最后几行。默认值是 all,也可以指定一个数字。 —no-color-禁用颜色输出,使日志更适合重定向到文件或其他工具。 —timestamps, -T-在日志输出中包含时间戳。 示例-
1)查看所有服务的日志
docker-compose logs2)查看特定服务的日志
docker-compose logs web3)查看特定服务的最后10行日志
docker-compose logs --tail 10 web4)查看所有服务的日志并包含时间戳
docker-compose logs -T9、使用多个Compose文件 你可以将配置拆分为多个文件-
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up四、docker-compose.yml 配置详解
1、Compose配置文件格式版本与Docker引擎的兼容性表
| Compose 文件格式 | 对应 Docker Engine 版本 |
|---|---|
| Compose specification | 19.03.0+ |
| 3.8 | 19.03.0+ |
| 3.7 | 18.06.0+ |
| 3.6 | 18.02.0+ |
| 3.5 | 17.12.0+ |
| 3.4 | 17.09.0+ |
| 3.3 | 17.06.0+ |
| 3.2 | 17.04.0+ |
| 3.1 | 1.13.1+ |
| 3.0 | 1.13.0+ |
| 2.4 | 17.12.0+ |
| 2.3 | 17.06.0+ |
| 2.2 | 1.13.0+ |
| 2.1 | 1.12.0+ |
| 2.0 | 1.10.0+ |
2、顶级配置项 version 定义了版本信息 services 定义了服务的配置信息 networks 定义了网络信息,提供给 services 中的 具体容器使用 volumes 定义了卷信息,提供给 services 中的 具体容器使用 示例-
version: "3.8" # Compose文件版本
services:
redis: # 服务名称
image: redis:alpine # 使用的镜像
ports:
- "6379" # 指定的端口
networks:
- frontend # 使用的网络
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
db:
image: postgres:9.4
volumes:
- db-data:/var/lib/postgresql/data
networks:
- backend
result:
image: nginx
ports:
- "5001:80"
networks:
- backend
depends_on:
- db
deploy:
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
worker:
image: nginx
networks:
- frontend
- backend
deploy:
mode: replicated
replicas: 1
labels: [APP=VOTING]
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 120s
networks:
frontend:
backend:
volumes:
db-data:3、version 常用版本 指定Docker Compose文件格式的版本。常用版本为3.8,3.7等。
4、services 配置指令 1)container_name
指定自定义容器名称,而不是生成的默认名称。
version: "3.8"
services:
redis:
image: redis:alpine
container_name: redis_test2)image
指定容器运行的镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。
version: "3.8"
services:
redis:
image: redis:alpine3)build
指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。
version: '3.8'
services:
webapp:
build: ./dir也可以使用 context 指令指定 Dockerfile 所在文件夹的路径(或者是git仓库的URL)。同时使用 dockerfile 指令指定 Dockerfile 文件名。
version: '3.8'
services:
webapp: #自定义发我名称 ,主要用查询
build:
context: ./dir
dockerfile: Dockerfile-name
注意-
如果同时指定了 image和 build, image 不在具有单独使用它的意义,而是指定了目前要构建的镜像的名称。 也就是说 Compose 会使用 build 指令中指定的 Dockerfile 构建的镜像,之后构建的镜像名称使用 image 中指定的名字 webapp:tag命名。
4)command
使用 command 可以覆盖容器启动后默认执行的命令。
写成shell形式
command: bundle exec thin -p 3000写成Dockerfile中的exec格式
command: [bundle, exec, thin, -p, 3000]5)depends_on
设置依赖关系。解决容器的依赖、启动先后的问题。
version: "3.8"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意-web 服务不会等待 redis 和 db 完全启动 之后才启动。
6)environment
添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。
environment:
RACK_ENV: development
SHOW: 'true'如果变量名称或者值中用到 true|false,yes|no 等表达布尔含义的词汇,最好放到引号里,避免 YAML 自动解析某些内容为对应的布尔语义。这些特定词汇如下-
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF 7)expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数-
expose:
- "3000"
- "8000"
8)ports
映射端口信息。
宿主机端口 : 容器端口 (即-HOST:CONTAINER) 的格式,或者仅仅指定容器的端口(宿主机将会随机选择端口)。
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"注意-当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML 会自动解析 xx:yy 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号括起来的字符串格式。
9)extra_hosts
添加主机名映射。类似 docker client —add-host。
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系-
162.242.195.82 somehost 50.31.209.229 otherhost 10)networks
配置容器连接的网络,引用顶级 networks 下的条目 。
services:
some-service:
networks:
some-network:
aliases:
- alias1
other-network:
aliases:
- alias2
networks:
some-network:
# Use a custom driver
driver: custom-driver-1
other-network:
# Use a custom driver which takes special options
driver: custom-driver-211)entrypoint
指定服务容器启动后执行的入口文件。
12)user
指定容器中运行应用的用户名。
13)working_dir
指定容器中工作目录。
14)restart
restart-
no-是默认的重启策略,在任何情况下都不会重启容器。 always-容器总是重新启动。 on-failure-在容器非正常退出时(退出状态非0),才会重启容器。 unless-stopped-在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器 restart: “no” restart: always restart: on-failure restart: unless-stopped 指定容器退出后的重启策略为始终重启。该命令对保持服务始终运行十分有效,在生产环境 中推荐配置为 always 或者 unless-stopped 。
restart: always 注-swarm 集群模式,请改用 restart_policy。
15)aliases
aliases -同一网络上的其他容器可以使用服务名称或此别名来连接到对应容器的服务。
services: some-service: networks: some-network: aliases: - alias1 - alias3 other-network: aliases: - alias2
16)healthcheck
用于检测 docker 服务是否健康运行。
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
interval: 1m30s # 设置检测间隔
timeout: 10s # 设置检测超时时间
retries: 3 # 设置重试次数
start_period: 40s # 启动后,多少秒开始启动检测程序17)env_file
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env也可以是列表格式-
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env18)Compose中的环境变量
你可以使用.env文件设置docker-compose.yml中使用的变量-
version: '3.8'
services:
web:
image: nginx
ports:
- "${HOST_PORT}:80".env文件-
```env
HOST_PORT=80805、volumes 配置指令 将主机的数据卷或者文件挂载到容器里。
version: "3.8"
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgresql/data"数据卷所挂载路径设置。可以设置宿主机路径 (HOST:CONTAINER) 或加上访问模式 (HOST:CONTAINER:ro)。
该指令中路径支持相对路径-
volumes:
- /var/lib/mysql
- cache/:/tmp/cache
- ~/configs:/etc/configs/:ro6、networks 配置指令 1)未显式声明网络环境
使用docker-compose up启动容器后,这些容器都会被加入app_default网络中。使用docker network ls可以查看网络列表,docker network inspect 可以查看对应网络的配置。
version: '3'
services:
web:
mage: nginx:latest
container_name: web
depends_on:
- db
ports:
- "9090:80"
links:
- db
db:
image: mysql
container_name: db2)networks关键字指定自定义网络
例如-下面的docker-compose.yml文件,定义了front和back网络,实现了网络隔离。其中proxy和db之间只能通过app来实现通信。其中,custom-driver-1并不能直接使用,你应该替换为host, bridge, overlay等选项中的一种。
version: '3.8'
services:
proxy:
build: ./proxy
networks:
- front
app:
build: ./app
networks:
- front
- back
db:
image: postgres
networks:
- back
networks:
front:
# Use a custom driver
driver: custom-driver-1
back:
# Use a custom driver which takes special options
driver: custom-driver-2
driver_opts:
foo: "1"
bar: "2"3)配置默认网络
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
networks:
default:
# Use a custom driver
driver: custom-driver-14)使用已存在的网络
networks:
default:
external:
name: my-pre-existing-network五、最佳实践
保持docker-compose.yml简洁-使用多个文件来分离开发和生产配置。 版本控制-将你的docker-compose.yml放入版本控制系统中,以管理跨环境的配置。 使用命名卷-确保数据在容器重启后依然存在。
version: '3.8' # 指定Compose文件的版本
services: # 定义多个服务
web: # Web服务,通常是前端或后端的应用
image: nginx:latest # 使用Nginx镜像
ports:
- "80:80" # 将容器的80端口映射到主机的80端口
volumes:
- ./web:/usr/share/nginx/html # 挂载本地目录到容器中
environment:
- NGINX_HOST=localhost # 设置环境变量
- NGINX_PORT=80
networks:
- frontend # 连接到前端网络
depends_on:
- app # 该服务将在'app'服务启动后才启动
restart: always # 在容器崩溃后总是重启
app: # 应用服务,可以是任何语言的后端服务
build: # 从Dockerfile构建镜像
context: ./app # Dockerfile所在的目录
dockerfile: Dockerfile # 使用的Dockerfile名称
ports:
- "3000:3000" # 将容器的3000端口映射到主机的3000端口
volumes:
- ./app:/usr/src/app # 挂载本地代码目录到容器中
environment:
- NODE_ENV=development # 设置环境变量
- PORT=3000
networks:
- frontend # 连接到前端网络
- backend # 连接到后端网络
depends_on:
- db # 该服务将在'db'服务启动后才启动
restart: on-failure # 仅在容器非正常退出时重启
db: # 数据库服务,使用MySQL
image: mysql:5.7 # 使用MySQL 5.7镜像
volumes:
- db_data:/var/lib/mysql # 持久化MySQL数据到命名卷
environment:
MYSQL_ROOT_PASSWORD: example # MySQL root用户的密码
MYSQL_DATABASE: example_db # 自动创建的数据库名称
MYSQL_USER: user # 创建的用户名称
MYSQL_PASSWORD: password # 用户密码
networks:
- backend # 连接到后端网络
restart: unless-stopped # 仅在手动停止时不重启
volumes: # 定义命名卷,用于数据持久化
db_data: # MySQL数据卷
networks: # 定义自定义网络
frontend: # 前端网络,连接web和app服务
backend: # 后端网络,连接app和db服务