• Docker compose


    Docker compose

    1. 介绍

    docker-compose 是 Docker 官方的开源项目,使用 python 编写,实现上调用了Docker 服务的 API 进行容器管理及编排,其官方定义为定义和运行多个 Docker 容器的应用。

    docker-compose 中有两个非常重要的概念:
    • 服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
    • 项目( project ):由一组关联的应用容器组成的一个完整业务单元,在 dockercompose.yml 文件中定义, 整个 docker-compose.yml 定义一个项目。
    Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周
    期管理。通过 compose 可以方便的管理多个服务。

    2. 为什么要 Docker Compose

    Docker 是一个轻量化的应用程序, Docker 官方推荐每个 Docker 容器中只运行一
    个进程。
    • 如果一个应用需要涉及到 MySQL、 nginx 等环境, 那么我们需要分别为应用、数
    据库和 nginx 创建单独的 docker 容器,然后分别启动容器。
    • 想象一下,当我们构建好 Docker 之后,每次启动应用,都至少需要 docker run
    三次, 或者写一些脚本来实现, 这样会比较繁琐。
    • 另外,这些 docker 容器都是分散独立的,也不方便镜像管理。那既然这些 docker
    容器 都是为了同一个应用服务,我们就应该把它们放到一起,这就引出了dockercompose 来解决这类型的问题。

    3. Docker Compose 文件(docker-compose.yml)

    目前官方支持三个大版本, 即 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    image

    指定容器运行的镜像。以下格式都可以:

    image: redis
    image: redis:5
    image:
    redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398
    bc4b991aac7
    image: library/redis
    image: docker.io/library/redis
    image: my_private.registry:5000/redis
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    command

    覆盖容器启动的默认命令

    command: ["nohup", "java", "-jar", "jarname", "&"]
    command: nohup java -jar jarname &
    
    • 1
    • 2
    version: '3.8'
    services:
      web:
        image: nginx:latest
        command: ["tail","-f","/etc/hosts"]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    entrypoint

    覆盖容器默认的 entrypoint。 Docker Compose中的entrypoint是一个可选的配置项,用于指定容器启动时要执行的命令或脚本。它可以在Dockerfile中定义,也可以在docker-compose.yml文件中定义。

    services:
      myservice:
        entrypoint: ["command", "arg1", "arg2"]
    
    • 1
    • 2
    • 3

    其中,"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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    示例

    version: '3.8'
    services:
      web:
        image: nginx:latest
        entrypoint:
          - tail
          - -f
          - /etc/os-release
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    environment

    添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以
    确保 YML 解析器不会将其转换为 True 或 False

    #map 语法
    environment:
      RACK_ENV: development
      SHOW: "true"
      USER_INPUT:
    #数组语法
    environment:
      - RACK_ENV=development
      - SHOW=true
      - USER_INPUT
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    示例

    version: '3.8'
    services:
      web:
        image: nginx:latest
        environment:
          TEST: 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    networks

    指定容器运行的网络

    version: '3.8'
    services:
      web:
        image: nginx:latest
        environment:
          TEST: 1
        # 绑定网络
        networks:
          - mywebnet1
          - mywebnet2
    # 创建网络
    networks:
      mywebnet1:
      mywebnet2:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    配置网络驱动和子网信息

    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"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    volumes

    将主机的数据卷或者文件挂载到容器里

    version: '3.8'
    services:
      web:
        image: nginx:latest
        volumes:
          - /data/maxhou/vol1:/usr/share/nginx/html
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    下面这段Docker Compose文件定义了一个服务(service)和一个卷(volume)。

    服务部分:

    • 服务名为"backend",使用镜像"awesome/backend"。
    • 定义了两个卷:
    • 第一个卷是一个命名卷,名为"db-data",将容器内的"/data"目录与主机上的一个卷进行绑定。这个卷设置了"nocopy"属性为true,表示在容器启动时不会将主机上的数据复制到容器内。
    • 第二个卷是一个绑定卷,将主机上的"/var/run/postgres/postgres.sock"文件与容器内的"/var/run/postgres/postgres.sock"文件进行绑定。

    卷部分:

    • 定义了一个名为"db-data"的卷。

    这段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:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    ports

    指定端口映射。

    version: '3.8'
    services:
      web:
        image: nginx:latest
        ports:
          - 8080:80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    以下格式也可以

    #完整语法
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    expose

    暴露端口,但不映射到宿主机,只被连接的服务访问。
    仅可以指定内部端口为参数

    expose:
      - "3000"
      - "8000"
    
    • 1
    • 2
    • 3

    depends_on

    设置依赖关系。
    • 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服务部分:

    • 使用mysql:5.7镜像作为容器的基础镜像。
    • 定义了一个环境变量MYSQL_ROOT_PASSWORD,其值为root。
    • 使用了healthcheck来检查mysql服务的健康状态。具体健康检查的配置如下:
    • test字段指定了检查命令,即通过mysql命令连接到数据库并执行’show databases;'语句。
    • interval字段指定了健康检查的间隔时间,每10秒进行一次检查。
    • timeout字段指定了每次健康检查的超时时间,超过5秒则认为检查失败。
    • retries字段指定了最大重试次数,如果连续10次检查都失败,则认为服务不健康。
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    env_file

    从文件添加环境变量。可以是单个值或列表的多个值

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4. 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列出所有容器使用的镜像
    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 upup 命令会构建,(重新)创建,启动,链接一个服务相关的容器
    docker compose version查看版本

    命令格式

    对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的
    服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服
    务都会受到命令影响。
    docker-compose 命令的基本的使用格式为

    docker compose [OPTIONS] COMMAND [ARGS...]
    
    • 1

    常见命令说明

    up

    该命令的作用十分强大,它会尝试自动完成包括构建镜像、(重新)创建服务、启动服
    务并关联服务相关容器的一系列操作,可以直接通过该命令来启动一个项目。

    docker compose up [options] [SERVICE...]
    
    • 1

    -d 在后台运行服务容器, 推荐在生产环境下使用该选项
    • --force-recreate 强制重新创建容器,不能与 --no-recreate 同时使用
    • --no-recreate 如果容器已经存在了,则不重新创建,不能与 --forcerecreate 同时使用

    down

    停止所有容器,并删除容器和网络

    docker compose down [options] [SERVICE...]
    
    • 1
    • -v, --volumes 删除容器同时删除目录映射run
    run

    该命令可以在指定服务容器上执行相关的命令

    # 例如:启动一个 ubuntu 服务容器,并执行 ping docker.com 命令
    # docker compose run ubuntu ping docker.com
    docker compose run [options] SERVICE [COMMAND] [ARGS...]
    
    • 1
    • 2
    • 3

    -d 后台运行容器
    • --name NAME 为容器指定一个名字
    • --entrypoint CMD 覆盖默认的容器启动指令
    • -e KEY=VAL 设置环境变量值,可多次使用选项来设置多个环境变量
    • -u, --user=“” 指定运行容器的用户名或者 uid
    • --rm 运行命令后自动删除容器
    • -p, --publish=[] 映射容器端口到本地主机

    5. 使用示例

    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:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    这段Docker Compose文件定义了三个服务(services):mysys、mysql和redis,并创建了一个网络(network)myhellonet。

    mysys服务部分:

    • 使用java:8镜像作为容器的基础镜像。
    • 将主机的6060端口映射到容器的6060端口。
    • 通过depends_on指定依赖关系,即mysys服务依赖于mysql和redis服务,并且只有当这两个服务健康时,mysys服务才会启动。
    • 使用nohup命令运行一个Java应用程序,命令为"java -jar /app/oj_java-0.0.1-SNAPSHOT.jar",并使用&符号将其放入后台运行。
    • 将主机上的"./app/“目录与容器内的”/app/"目录进行绑定。
    • 将mysys服务连接到myhellonet网络。

    mysql服务部分:

    • 使用mysql:5.7镜像作为容器的基础镜像。
    • 定义了一个环境变量MYSQL_ROOT_PASSWORD,其值为"root"。
    • 将主机上的"./mysql/varlib/“目录与容器内的”/var/lib/mysql"目录进行绑定。
    • 将主机上的"./mysql/init/“目录与容器内的”/docker-entrypoint-initdb.d/"目录进行绑定。
    • 使用healthcheck来检查mysql服务的健康状态。具体健康检查的配置与之前的示例相同。

    redis服务部分:

    • 使用redis:7镜像作为容器的基础镜像。
    • 将redis服务连接到myhellonet网络。
    • 使用命令"redis-server --protected-mode no --bind 0.0.0.0"来启动redis服务器。
    • 使用healthcheck来检查redis服务的健康状态。具体健康检查的配置与之前的示例相同。

    networks部分:

    • 定义了一个名为myhellonet的网络。

  • 相关阅读:
    Feign常用的注解、Http请求调用
    Alibaba 官方上线,SpringBoot+SpringCloud 全彩指南(第五版)
    【C++】:继承
    阅读芯片源码(RTL)
    JDK1.8新特性
    网站流量不是很多,还有这几十种途径让网站变现转化
    D. Make It Round(贪心 贡献 数学)[Codeforces Round #834 (Div. 3)]
    基于正交分解的室外阴影图像恢复
    Python的基础语法之数据类型
    TiDB Lightning 命令行参数
  • 原文地址:https://blog.csdn.net/weixin_53946852/article/details/133105345