DockerCompose 容器编排
1. 什么是 DockerCompose
一个完整的项目是需要多个服务的,比如一个 Web 应用程序,它需要 MySQL、Redis、Nginx 等服务。那么我们需要分别为应用、数据库和 nginx 创建单独的 docker 容器,然后分别启动容器。 构建好 Docker 之后,每次启动应用,都至少需要 docker run 三次,这样会比较繁琐;另外,这些 docker 容器都是分散独立的,也不方便镜像管理。这就引出了 docker compose 来解决这类型的问题。
Docker Compose 使用 YAML 文件来配置应用程序的服务,包括容器映像、容器之间的网络连接、卷挂载以及其他运行时配置选项,它面向的是整个应用程序。
2. Docker 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
- 指定容器运行的镜像
# 下面的格式都可以
image: redis
image: redis:5
image: redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7
# 自己的仓库/镜像
image: library/redis
image: docker.io/library/redis
image: my_private.registry:5000/rediscommand
- 指定容器启动后执行的命令,覆盖 Dockerfile 中的默认命令
command: ["bundle", "exec", "rails", "server", "-p", "3000"]
# 或
command: bundle exec rails server -p 3000entrypoint
entrypoint用于设置容器启动时要执行的默认命令或脚本。与cmd不同,entrypoint用于指定容器启动时的主要命令,而cmd则提供额外的默认参数。
entrypoint: /code/entrypoint.shentrypoint 配置信息。它告诉 Docker 在启动容器时执行 /code/entrypoint.sh 脚本。
environment
- 添加环境变量。
# 例如:设置 MySQL 的密码
environment:
- MYSQL_ROOT_PASSWORD=123456
# 或
environment:
MYSQL_ROOT_PASSWORD: 123456- 如果是布尔值
布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 Falsevolumes
- 指定挂载到容器中的卷,可以是一个本地路径或者一个已存在的卷名称
version: '3.8'
services:
# web 是一个自己取名称
web:
# 镜像
image: nginx:1.24.0
# 卷的配置
volumes:
# 命名卷
- type: volume
source: db-data
target: /data
# 绑定卷
- type: bind
source: /root/data # 宿主机
target: /data # 容器
# 创建一个卷
volumes:
db-data:也可以如下格式
volumes:
- "db-data:/data"
- "/root/data:/data"networks
- 指定容器运行的网络。
version: '3.8'
services:
# web 是一个自己取名称
web:
# 镜像
image: nginx:1.24.0
# 加入指定网络
networks:
- mynetwork1
- mynetwork2
# 创建两个网络
networks:
mynetwork1:
mynetwork2:ports
ports:
- target: 80
host_ip: 0.0.0.0
published: 8080
- target: 80
host_ip: 127.0.0.1
published: 8000-9000- 第一个端口映射:
target: 80:容器内部的目标端口是 80。 host_ip: 0.0.0.0:宿主机的 IP 地址是 0.0.0.0,表示监听所有网络接口。 published: 8080:将容器的端口 80 映射到宿主机的端口 8080。
- 第二个端口映射:
target: 80:容器内部的目标端口是 80。 host_ip: 127.0.0.1:宿主机的 IP 地址是 127.0.0.1,表示只监听本地回环接口。 published: 8000-9000:将容器的端口 80 映射到宿主机的端口范围 8000-9000。
ports 第二种
ports:
- '5000:5000'改左边 就是宿主机映射的端口
expose
- 暴露容器端口,但不映射到宿主机,只被连接的服务访问。
expose:
- "3000"
- "8000"depends_on
- 指定容器启动的依赖关系,可以指定服务名称,也可以指定服务名称和条件。
version: "3.7"
services:
# 服务1
web:
# 依赖 db、redis 服务
depends_on:
- db
- redis
# 服务2
redis:
image: redis
# 服务3
db:
image: mysqlweb 服务依赖于 db 和 redis 服务,所以在启动 web 服务之前,Docker Compose 会等待 db 和 redis 服务处于启动状态。
services:
mysqlCompose:
image: mysql:8.0-debian
ports:
- '3306:3306'
volumes:
- /D/docker/mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: login_test
MYSQL_ROOT_PASSWORD: 123456
healthcheck:
test: mysql --user=root --password='123456' -e "SELECT 1;"
interval: 10s
timeout: 5s
retries: 10
redisCompose:
image: redis:alpine3.22
ports:
- '6379:6379'
environment:
REDIS_PASSWORD : 123456
volumes:
- /D/Docker/redis/redis.conf:/ect/redis/redis.conf
command: redis-server --requirepass 123456
healthcheck:
test: ["CMD", "redis-cli", "auth", "123456", "ping"]
interval: 10s
timeout: 5s
retries: 5
nginxCompose:
image: nginx:stable-alpine
ports:
- '80:80'
volumes:
- /D/Docker/nginx:/usr/share/nginx/html
nest1:
build:
context: ./
dockerfile: ./Dockerfile
depends_on:
mysqlCompose:
condition: service_healthy
redisCompose:
condition: service_healthy
ports:
- '5000:5000'condition: service_healthy:指定了 web 服务只有在 mysql 服务处于健康状态时才会启动。healthcheck定义了健康检查
test:指定了检查 MySQL 是否能够成功连接和执行查询语句。 interval:指定了检查间隔为 10 秒。 timeout:指定了检查超时时间为 5 秒。 retries:指定了最大重试次数为 10 次。
综合案例
注意
运行前 一定要把你的配置文件里面凡是涉及到地址的都改成宿主机的 IP 地址
比如 nest 环境配置文件 redis 里面的 host 或者 mysql 里面的 host 都改成宿主机的 IP 地址
services:
mysqlCompose:
image: mysql:8.0-debian
ports:
- '3306:3306'
volumes:
- /D/docker/mysql:/var/lib/mysql
environment:
MYSQL_DATABASE: login_test
MYSQL_ROOT_PASSWORD: 123456
healthcheck:
test: mysql --user=root --password='123456' -e "SELECT 1;"
interval: 10s
timeout: 5s
retries: 10
redisCompose:
image: redis:alpine3.22
ports:
- '6379:6379'
environment:
REDIS_PASSWORD : 123456
volumes:
- /D/Docker/redis/redis.conf:/ect/redis/redis.conf
command: redis-server --requirepass 123456
healthcheck:
test: ["CMD", "redis-cli", "auth", "123456", "ping"]
interval: 10s
timeout: 5s
retries: 5
nginxCompose:
image: nginx:stable-alpine
ports:
- '80:80'
volumes:
- /D/Docker/nginx:/usr/share/nginx/html
nest1:
build:
context: ./
dockerfile: ./Dockerfile
depends_on:
mysqlCompose:
condition: service_healthy
redisCompose:
condition: service_healthy
ports:
- '5000:5000'Docker Compose 命令
| 命令 | 功能 |
|---|---|
| docker compose build | 构建服务 |
| docker compose config | 规范的格式来显示服务配置 |
| docker compose cp | 在本地系统和服务容器直接拷贝文件 |
| docker compose create | 创建服务的容器 |
| docker compose down | 停止所有容器,并删除容器 |
| docker compose events | 从服务器获取实时事件 |
| docker compose exec | 在容器中执行命令 |
| docker compose images | 列出所有容器使用的镜像 |
| docker 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 stop | 停止当前运行的某个容器 |
| docker compose top | 显示运行的进程 |
| docker compose unpause | 恢复服务 |
| docker compose up | up 命令会构建,(重新)创建,启动,链接一个服务相关的容器。 |
| docker compose version | 查看版本 |
最重要两个命令
docker compose up
- 启动所有服务。 -d 在后台运行服务容器。 --force-recreate:强制重新创建容器,不能与 --no-recreate 同时使用。 --no-recreate:如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用。 -f:指定使用的 Compose 模板文件,默认为 docker-compose.yml。 -p:指定项目名称,默认将使用所在目录名称作为项目名。
# 指定 config.txt 为模板文件,并且名称为 prj2
docker compose -f config.txt -p prj2 up -ddocker compose down
- 停止并删除所有服务。
docker compose down [options] [SERVICE...]