什么是docker compose

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

docker-compose 中有两个非常重要的概念:

        服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。

        项目( project ):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义, 整个 docker-compose.yml 定义一个项目。

Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周 期管理。通过 compose 可以方便的管理多个服务。

为什么需要docker compose

        • Docker 是一个轻量化的应用程序,Docker 官方推荐每个 Docker 容器中只运行一 个进程

         如果一个应用需要涉及到 MySQLnginx 等环境, 那么我们需要分别为应用、数 据库和 nginx 创建单独的 docker 容器,然后分别启动容器。

        • 想象一下,当我们构建好 Docker 之后,每次启动应用,都至少需要 docker run 三次, 或者写一些脚本来实现, 这样会比较繁琐。

        • 另外,这些 docker 容器都是分散独立的,也不方便镜像管理。那既然这些 docker 容器 都是为了同一个应用服务,我们就应该把它们放到一起,这就引出了 docker compose 来解决这类型的问题。

docker compose功能

1、使用步骤

        • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中 一起运行。

        • 最后,执行 docker compose up 命令来启动并运行整个应用程序。

2、核心功能

Compose 具有管理应用程序整个生命周期的命令:

        • 启动,停止和重建服务

        • 查看正在运行的服务的状态

        • 流式传输运行服务的日志输出

        • 在服务上运行一次性命令

docker compose使用场景

单主机部署

        快速搭建一个单节点开发或者测试环境,方便使用。

不同环境隔离

        通过指定 project 来运行不同的环境,实现隔离的目的。

docker compose文件

文件语法版本

        目前官方支持三个大版本, 即 Version 1、Version 2 Version 3, 其中 Version 1 已 经被废弃掉了。

        当前最新的版本是 3.8,它支持的 Docker Engine 版本不得低于 19.03.0。 本课程主 要基于 3.8 版本的 Compose file 语法进行讲解,其他版本介绍参见https://docs.docker.com/reference/compose-file/legacy-versions/

文件基本结构及常见指令

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:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398 bc4b991aac7

image: library/redis

image: docker.io/library/redis

image: my_private.registry:5000/redis

创建一个docker-compose.yml文件,并编写内容

然后构建,执行命令        docker compose up -d

就创建了服务的网络和容器,并把容器和网络关联。

进行清理,执行命令        docker compose down

command

覆盖容器启动的默认命令。

command: ["bundle", "exec", "thin", "-p", "3000"]

command: bundle exec thin -p 3000

在yml中加入如下

然后构建,查看启动的容器的详情,cmd字段就被改了

但是也导致,nginx没有完成启动。

执行命令        docker exec -it prj2-web-1 curl 127.0.0.1

因为command命令把nginx的启动命令换了,所以nginx压根没有启动。

entrypoint

覆盖容器默认的 entrypoint

entrypoint: /code/entrypoint.sh

也可以是以下格式:

entrypoint:

        - php

        - -d

        - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so

        - -d

        - memory_limit=-1

        - vendor/bin/phpunit

对yml文件进行修改

然后构建,检查启动容器的详情,Entrypoint就被改了

但是也导致,nginx没有完成启动。

执行命令        docker exec -it prj2-web-1 curl 127.0.0.1

是因为entrypoint也将nginx的启动命令覆盖了

environment

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

#map 语法

environment:

        RACK_ENV: development

        SHOW: "true"

        USER_INPUT:

#数组语法

environment:

        - RACK_ENV=development

        - SHOW=true

        - USER_INPUT

修改yml文件

然后构建,查看容器详情中的Env字段

环境变量就配进去了

networks

指定容器运行的网络:

配置容器网络

services:

        frontend:

                image: awesome/webapp

                networks:

                        - front-tier

                        - back-tier

        monitoring:

                image: awesome/monitoring

                networks:

                        - admin

        backend:

                image: awesome/backend

                networks:

                        back-tier:

                                aliases:

                                        - database

                admin:

                        aliases:

                                - mysql

networks:

        front-tier:

        back-tier:

        admin:

配置网络驱动和子网信息

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"

修改yml文件。

执行命令        docker compose config

如果正常打印,就说明语法是ok的。

构建项目,然后查看容器详情的网络字段

volumes

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

#短语法

services:

        db:

                image: postgres:latest

                volumes:

                        - "/localhost/postgres.sock:/var/run/postgres/postgres.sock"

                        - "/localhost/data:/var/lib/postgresql/data"

#完整语法

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:

修改yml文件

执行命令        docker compose config

语法有问题会报错,没问题就会对yml解释

构建项目,然后再进入容器访问nginx主页

返回错误页面。

然后再宿主机的绑定卷位置创建index.html

在容器内部再次访问nginx主页

访问成功。也就是容器和宿主机目录完成了数据绑定。

ports

指定端口映射。以下格式都可以:

#完整语法

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"

修改yml文件

执行命令        docker compose config解释配置

语法有问题会报错,没问题就会对yml解释

构建项目,查看容器和宿主机的映射端口,执行命令        docker port prj6-web-1

web端访问端口

expose

暴露端口,但不映射到宿主机,只被连接的服务访问。

仅可以指定内部端口为参数:

expose:

        - "3000"

        - "8000"

修改yml文件

检查语法和解释配置,执行命令        docker compose config

build

指定为构建镜像上下文路径:

例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:

version: "3.7"

services:

        webapp:

                build: ./dir

或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile args

version: "3.7"

services:

        webapp:

                build:

                        context: ./dir

                        dockerfile: Dockerfile-alternate

                        args:

                                buildno: 1

                        labels:

                                - "com.example.description=Accounting webapp"

                                - "com.example.department=Finance"

                                - "com.example.label-with-empty-value"

context:上下文路径。

dockerfile:指定构建镜像的 Dockerfile 文件名。

args:添加构建参数,这是只能在构建过程中访问的环境变量。

labels:设置构建镜像的标签。

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 之前停止。

version: "3.7"

services:

        web:

                build: .

                depends_on:

                        - db

                        - redis

        redis:

                image: redis

        db:

                image: postgres

可以指定条件,healthy 需要配置 healthcheck 来完成

services:

        web:

                build: .

                depends_on:

                        db:

                                condition: service_healthy

                        redis:

                                condition: service_started

        redis:

                image: redis

        db:

                image: postgres

health check 样例

version: "3.8"

services:

        web:

                image: nginx:1.24.0

                environment:

                        TEST: 1

                depends_on:

                        mysql:

                                condition: service_healthy

        mysql:

                image: mysql:5.7

                environment:

                        MYSQL_ROOT_PASSWORD: "bit@123"

                volumes:

                        - /data/maxhou/mysqldata/varlib/:/var/lib/mysql

                healthcheck:

                        test: mysql --user=root --password='bit@123' -e "SELECT 1;"

                        interval: 10s

                        timeout: 5s

                        retries: 10

修改yml文件

检查语法和解释配置,执行命令        docker compose config

然后构建项目

刚刚构建时,web容器已经创建了,但是mysql容器没有走到Healthy状态

当mysql走到Healthy状态后,web服务马上就走到了Started状态了

查看运行的容器

可以看到web服务是后启动的。

env_file

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

env_file: .env

也可以是列表格式:

env_file:

        - ./common.env

        - ./apps/web.env

        - /opt/secrets.env

修改yml文件

并写好环境变量文件

检查语法和解释配置,执行命令        docker compose config

构建项目,进入容器查看环境变量

docker compose命令

命令官方文档

https://docs.docker.com/reference/cli/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 命令会构建,(重新)创建,启 动,链接一个服务
相关的容器。默 认情况下如果容器已经存在,将会 停
止并尝试重新创建他们。并使用 之前挂载的卷。--no-recreate
参数 可以让容器不被停止或者重新创 建,-d 表示后台运行
docker compose
version
查看版本

命令格式

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

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

常见选项

※※※-f, --file 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可 以多次指定

※※※-p, --project-name 指定项目名称,默认将使用所在目录名称作为项目名

执行命令        docker compose -f ./prj9/dockercompose.txt -p prj92 up -d

然后在查看构建的项目,执行命令        docker compose -p prj92 ps

-f选项是指定配置文件。如果没给-f,就会找当前目录下的配置文件

-d是指定构建的项目名称。如果没给-d,就会使用当前目录为项目名称

常见命令

up

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

语法

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

参数

        -d 在后台运行服务容器, 推荐在生产环境下使用该选项

        • --force-recreate 强制重新创建容器,不能与 --no-recreate 同时使用

        • --no-recreate 如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用

1、构建项目,查看创建容器的环境变量

构建项目,执行命令        docker compose up -d

查看创建容器的环境变量,执行命令        docker container inspect prj1-web-1

2、修改yml文件的环境变量

3、然后使用强制重新创建容器,使用--force-recreate

执行命令        docker compose up -d --force-recreate

然后再次查看容器的环境变量

4、再次修改yml文件

5、然后再次构建项目 使用--no-recreate参数

执行命令        docker compose up -d --no-recreate

6、再次查看容器环境变量

环境变量依旧没变,说明构建并未重新读取配置文件创建容器

down

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

语法

        docker compose down [options] [SERVICE...]

参数

        -v, --volumes 删除容器同时删除目录映射

修改yml文件

构建项目,再清理项目

然后再次清理,加上-v参数

run

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

语法

        # 例如:启动一个 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=[] 映射容器端口到本地主机

创建web服务的容器

执行命令        docker compose run -d --name nginx1 web

查看运行的容器

再次创建web2服务的容器,并指定执行一条命令(请求百度)。

执行命令        docker compose run --name nginx2 web curl www.baidu.com

基本操作

1、编辑yml文件,配置服务拓扑和检查关系

2、检查语法和解释配置,执行命令        docker compose config

3、编辑yml文件,配置网络、nginx首页和存储卷和映射端口

version: "3.8"
services:
  web:
    image: nginx:1.24.0
    environment:
      TEST: 3
    networks:
      - mytestnetwork
    volumes:
      - ./nginxhome:/usr/share/nginx/html
    ports:
      - 8081:80
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 704756098
    networks:
      - mytestnetwork
    volumes:
      - ./mysqllib:/var/lib/mysql
    healthcheck:
      test: mysql -u root -p704756098 -e "select 1;"
      interval: 10s
      timeout: 5s
      retries: 10
  redis:
    image: redis::7
    networks:
      - mytestnetwork
    healthcheck:10
  redis:
    image: redis:7
    networks:
      - mytestnetwork
    healthcheck:
      test: redis-cli ping
      interval: 10s
      timeout: 5s
      retries: 10
networks:
  mytestnetwork:

4、检查语法和解释配置,执行命令        docker compose config

5、然后在宿主机上创建nginx绑定卷的目录,并进入,编写nginx主页

5、构建和启动项目

执行命令        docker compose up -d

在web端访问nginx主页

查看创建网络关联的容器

查看mysql绑定卷目录

查看nginx主页绑定卷目录

6、清理项目

执行命令        docker compose down

部署自定义服务

服务拓扑

1、编写数据库脚本,初始化数据库

drop database if exists test;

CREATE DATABASE `test` DEFAULT CHARACTER SET utf8mb4;

use `test`;

CREATE TABLE `users`(
 `sno` int(11) DEFAULT NULL,
 `sname` varchar(50) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO users (sno,sname) VALUES
 (1,'pony'),
 (2,'maxhou');

把这份数据库初始化脚本保存为init.sql文件

2、编写java应用

将步骤1的脚本,在本地建好。

在本地编写一个Maven项目,然后测试好能在本地访问。打成jar包

3、编写yml配置文件,也就是服务拓扑编写,进行容器编排

version: "3.8"
services:
  web:
    image: nginx:1.24.0
    environment:
      TEST: 3
    volumes:
      #配置反向代理。nginx会自动加载/etc/nginx/conf.d下的配置文件
      - ./nginxconf/:/etc/nginx/conf.d
    depends_on:
      backend:
        condition: service_started
    ports:
      - 8081:80
  backend:
    image: openjdk:8
    #启动springboot应用
    command: java -jar /app/testmymysql-0.0.1-SNAPSHOT.jar
    volumes:
       #将宿主机上的jar包共享给容器
      - ./app/:/app/
    depends_on:
      mysql:
        condition: service_healthy
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 704756098
    volumes:
       #mysql数据备份保存
      - ./mysql/varlib/:/var/lib/mysql
       #mysql启动会默认运行/docker-entrypoint-initdb.d/目录下的脚本文件,将数据库脚本放到宿主机中的绑定卷位置,就能初始化数据库
      - ./mysql/initdb/:/docker-entrypoint-initdb.d/
    healthcheck:
      test: mysql -u root -p704756098 -e 'select 1;'
      interval: 10s
      timeout: 5s
      retries: 10

反向代理的配置文件是./nginxconf/testsql.conf

内容如下

server {
    listen 80;//监听80端口
    access_log off;//关闭访问日志
    location / {//location /匹配任何路径
        proxy_pass http://backend:8080/user/; //代理到http://backend:8080/user/路径
    }
}

凡是打到 nginx 80 端口的请求,全部静默地转给后端 backend:8080,并在前面统一加上 /user/ 路径前缀

4、检查服务是否正常

构建启动项目,进行访问

5、项目清理

执行命令        docker compose down

部署WordPress

服务拓扑

1、编写配置文件

version: "3.8"
services:
  wordpress:
    image: wordpress
    restart: always
    depends_on:
      db:
        condition: service_healthy
    ports:
      - 8081:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: mywordpressuser
      WORDPRESS_DB_PASSWORD: mywordpresspass
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wordpress:/var/www/html
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
      MYSQL_USER: mywordpressuser
      MYSQL_PASSWORD: mywordpresspass
    volumes:
      - ./mysqlvarlib:/var/lib/mysql
    healthcheck:
      test: mysql -u root -proot -e "select 1;"
      interval: 10s
      timeout: 5s
      retries: 10

2、执行命令检查        vim docker-compose.yml

3、运行站点

执行命令        docker compose up -d

然后在web端访问8081端口访问主页

点击简体中文进行安装。

进行登录

登录成功

4、编写文章,测试是否正常

5、项目清理

执行命令        docker compose down

常见问题

1. uprun start 之间有什么区别

        通常,你想要 docker compose up. 用于 up 启动或重新启动 docker-compose.yml. 在默认的“附加模式下,会看到来自所有容器的所有日志。在分离模式 ( -d) 中,启 动容器后 Compose 退出,但容器继续在后台运行。

        该 docker compose run 命令用于运行一次性临时任务。它需要您要运行的服 务名称,并且只为正在运行的服务所依赖的服务启动容器。用于 run 运行测试或执行 管理任务,例如从数据卷容器中删除或添加数据。该 run 命令的作用类似于 docker run -ti 它打开容器的交互式终端并返回与容器中进程的退出状态匹配的退出状态。 docker compose start 命令仅对重新启动先前创建但已停止的容器有用。它从不创 建新容器。

2. 如何在同一主机上运行 Compose 文件的多个副本

Compose 使用项目名称为项目的所有容器和其他资源创建唯一标识符。要运行项目的 多个副本,请使用-p 命令行选项 或 COMPOSE_PROJECT_NAME 环境变量设置自定 义项目名称。

3. 可以控制服务启动顺序吗?

可以控制启动顺序,通过依赖指定,并且可以配合 healthcheck 等健康检查成功以后 再启动。

更多推荐