Docker Compose

简介

  1. 对于现代应用来说,大多都是通过很多的微服务互相协同组成的一个完整应用。例如,订单管理、用户管理、品类管理、缓存服务、数据库服务等,它们构成了一个电商平台的应用。而部署和管理大量的服务容器是一件非常繁琐的事情。而 Docker Compose 就是解决这类问题的。

  2. Docker Compose 是一个需要在 Docker 主机上进行安装的 Docker 容器编排外部工具。其并不是通过脚本或各种冗长的 Docker 命令来将应用组件组织起来,而是通过一个声明式的配置文件描述整个应用,然后通过一条命令完成应用部署。部署成功后,还可通过一系列简单命令实现对其完整生命周期的管理。

  3. Docker Compose的前身是由Orchard Laboratories公司开发的Fig项目。Orchard Laboratories是一家在2011年成立的英国创业公司,专注于提供Docker托管服务。在2014年,Docker公司收购了Orchard Laboratories,并将Fig项目纳入自己的项目群,进一步发展成为了我们现在所熟知的Docker Compose。

compose文件

一、 文件简介

Docker Compose 使用 YAML 文件来定义服务。官方推荐的默认文件名为 compose.yml ,但同时也支持 docker-compose.yml。由于一个 compose 文件中定义的为一个项目的所有服务,所以一般为在创建 compose文件之前先新建一个目录,目录名称一般为项目名称,然后再将项目所需的所有镜像、微服务的 Dockerfile 放入该目录,并在该目录中新建 compose 文件。

compose 文件中包含 6 个顶级属性:version、services、networks、volumes、configs 与secrets,及很多的它们下面所包含的属性。下面简单介绍一下常用的属性。

二、 version

version是一个顶级属性,从Docker Compose 1.27.0开始,version属性已经被标记为过时。这是因为Docker Compose现在可以根据Compose文件中使用的特性自动确定版本,所以不再需要手动指定。虽然version属性已经过时,但在现有的Docker Compose文件中仍然可以使用,不会报错。只是在新的Compose文件中,我们不再推荐使用它。

三、 services

services 是一个顶级属性,用于定义一个应用中所包含的服务。Docker Compose 会将每个服务部署在各自的容器中。其下包含的第一级的属性即为服务名称,这个名称可以根据服务内容随意命名。而在服务名称下还可包含很多的属性,常用属性如下:

1. build:

用于指定一个 Dockerfile 的路径。而该 Dockerfile 则是用于创建当前服务镜像的。这个路径可以是以斜杠(/)开头的绝对路径,也可以是相对于当前 compose 文件的、以点(.)号开头的相对路径。如果 Dockerfile 文件名不是默认名称,则需要通过 build 下的 context 属性指定路径dockerfile 属性指定文件名

# 层级关系用两个空格键表示,而不是Tab键
# 每个:后面一定要有一个空格
services:
  mysqlDB:
  	build:
      context: ./
      dockerfile: myDockerfile
2. image

用户指定当前服务所需要使用的镜像,这个镜像可以是本地镜像,也可以是远程镜像仓库中的镜像(会自动 pull)。如果设置了 build,此时再设置的 image 属性即为构建出的镜像的名称与 Tag。

services:
  mysqlDB:
  	image: mysql:8.0
3. container_name

该属性用于设置容器名称,但并不是必须的。如果没有设置该属性,容器名称则会采用“合成方式”。而合成时需要用到 services 下的第一级属性。在 services 下存在一级属性,称为服务名称。该级属性是作为 services 下的第一级属性出现的。服务名称将来会作为容器名称的一部分出现。容器的名称格式为:当前 compose文件所在目录名_ 服务名称。

services:
  mysqlDB:
  	image: mysql:8.0
  	container_name: mysql_container
4. ports

一个列表。前面为暴露出的端口号,后面为容器中应用的端口号。如果仅设置了一个端口号,那么这个端口号是容器中应用的端口号,其暴露到宿主机的端口号会被随机分配。

services:
  mysqlDB:
  	image: mysql:8.0
  	ports: 
  	  - 80:80    # 绑定容器的 80 端口到主机的 80 端口
      - 9000:80  # 绑定容器的 80 端口到主机的 9000 端口
      - 443      # 绑定容器的 443 端口到主机的任意端口
5. command

用于覆盖 Dockerfile 中的 CMD 指令内容,即启动该服务容器后立即运行的命令。如果直接按照Dockerfile中的CMD指令内容执行即可,则compose文件中无需该command属性。command属性的语法和Dockerfile中的语法一样,有shell和exec两种语法。

services:
  mysqlDB:
  	image: mysql:8.0
  	command: ["/bin/bash","-c" "pwd"]
6. depends_on

一个列表。用于指定当前服务的启动所依赖的应用名称。即列表中指定的服务会先于当前服务启动。

services:
  mysqlDB:
  	image: mysql:8.0
  	depends_on: 
  	  - nginx
  	  - initConf
7. deploy

用于指定当前服务容器的部署设置,它只在Swarm模式下有效。其下有一个常用属性 replicas,用于指定该服务启动的容器的数量。即实现一个服务多个容器。一旦指定了 deploy: replicas,就不能再指定container_name 属性了。因为各个启动的容器名称不能相同,而只能由系统自动生成。

services:
  mysqlDB:
    image: mysql:8.0
    deploy:
      mode: replicated
      replicas: 6
8. networks

用于指定当前服务容器要连接到的网络。该网络必须是已经存在的,或通过顶级属性networks 创建的网络。

# 将mysqlDB服务连接到frontend和backend两个网络:
services:
  mysqlDB:
    image: mysql:8.0
    networks: 
      - frontend
      - backend

需要注意以下几点:

  • 如果你没有指定任何网络,那么服务将会连接到一个默认的网络,这个网络的名称是项目名_default
  • 如果你指定了多个网络,那么服务的容器将会有多个网络接口,每个网络接口连接到一个网络。
  • 你可以使用docker network create命令或者Docker Compose的networks选项来创建网络。
9. volumes

用于指定当前服务容器所使用到的所有 volume。这些 volume 可以使用路径与卷标两种方式。例如,下面是路径方式,非常直观,易于查看,但需要管理本地路径。volumes属性值的格式是<宿主机路径>:<容器路径>

services:
  mysqlDB:
    image: mysql:8.0
    volumes: 
      - /etc/mysql:/var/lib/mysql

再如,下面是卷标方式。volumes属性值的格式是<数据卷名>:<容器路径>backend 与 backup 两个服务共享了 db-data 的卷,逻辑简洁明了,且无需管理本地路径。但具体卷标所代表的是 Docker 主机的哪个路径,并不能直观的看到。需要通过 docker volume inspect [卷标]来查看。

services:
  backend:
    image: awesome/database
    volumes:
      - db-data:/var/lib/backend/data
  backup:
    image: backup-service
    volumes:
      - db-data:/var/lib/backup/data
volumes:
  db-data:

四、 networks

networks 作为一个顶级属性,用于定义和创建应用中所使用到的所有网络。其下包含的第一级属性即为网络名称,这个网络名称可以随意命名。而在网络名称下还可包含很多的属性,常用属性如下:

1. name

name属性允许你为网络指定一个自定义的名称。默认情况下,也就是不使用name属性的时候,创建的网络名称将为<项目名>_<网络名>。如果你为网络指定了name属性,那么网络将直接使用这个名称,而不是默认的名称。

networks:
  mynetwork:
    name: my_custom_network

在这个例子中,由于设置了name属性,所以创建的网络的名称将为 my_custom_network,而不是默认的<项目名>_mynetwork。

2. driver

用于指定网络驱动,缺省驱动为 bridge。

3. attachable

attachable属性允许单独的服务或者容器连接到指定的网络。默认情况下,由Docker Compose创建的网络只能被在同一个Compose文件中定义的服务所使用。但是如果你将网络设为attachable,那么其他的服务或者容器也可以连接到这个网络。

networks:
  mynetwork:
    driver: overlay
    attachable: true

在这个例子中,mynetwork 是一个 attachable 网络,所以你可以在 docker run 命令中使用 --network=mynetwork 选项,将单独的容器连接到这个网络。需要注意的是,attachable 选项只对 overlay 和 macvlan 网络驱动有效。

五、volumes

volumes 作为一个顶级属性,用于定义和创建应用中所使用到的所有 volume。其下包含的第一级属性即为 volume 的卷标,这个卷标可以随意命名。这个卷标所代表的是当前 Docker主机中的目录,至于该目录的具体位置,是由系统自动分配的。由于前面的services属性下已经用过volumes的用法了,所以这里不再过多展开。

常用命令

Docker Compose通过docker-compose系列命令查看和控制compose中的所有服务容器。

  1. docker-compose pull

    拉取 compose 中服务依赖的全部镜像或指定镜像。通过在命令后添加服务名称来指定。

  2. docker-compose config

    检查 compose 文件是否正确。可添加选项-q,表示只有存在问题时才有输出。

  3. docker-compose up

    启动 compose 中的所有容器。-d 选项表示后台启动。

  4. docker-compose logs

    查看 comopse 中所有服务或指定服务的运行日志。通过在命令后添加服务名称来指定。默认情况下,将对不同的服务日志使用不同的颜色来区分。

  5. docker-compose ps

    列出 compose 中所有服务或指定服务。通过在命令后添加服务名称来指定。

  6. docker-compose top

    列出 compose 中当前正在运行的所有服务或指定服务。通过在命令后添加服务名称来指定。

  7. docker-compose images

    列出 compose 中所有服务或指定服务对应的镜像。通过在命令后添加服务名称来指定。

  8. docker-compose port

    列出指定服务容器的指定端口所映射的宿主机端口。

  9. docker-compose run

    在指定服务上执行一条命令。

  10. docker-compose exec

    进入指定服务容器。通过在命令后添加服务名称来指定。

  11. docker-compose pause

    暂停 compose 中所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。

  12. docker-compose unpause

    恢复 compose 中处于暂停状态的所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。

  13. docker-compose stop

    停止 compose 中所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。

  14. docker-compose restart

    重启 compose 中所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。

  15. docker-compose start

    启动 compose 中所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。

  16. docker-compose kill

    通过发送 SIGKILL 信号停止指定服务的容器。

  17. docker-compose rm

    删除 compose 中的、处于停止状态的所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。

  18. docker-compose down

    停止并删除 compose 中的所有服务容器、网络、镜像、数据卷。

项目搭建

现在搭建一个使用go语言编写的后端网站,后端架构采用gin框架、mysql和redis数据库。有一个用户表和一个文章表。不过部分接口还为实现,因为这个demo项目只是为了使用docker compose工具,所以业务逻辑写的很草率。该项目的地址:https://gitee.com/Free_Software/goBlog.git

由于我是在windows系统下面编写的go代码,所以需要使用交叉编译的方式生成一个项目的可执行文件。操作截图如下:

image-20230920162819239

这样就会生成一个文件名为main的可以在linux系统上运行的可执行文件。接下来就需要在centos系统下创建一个目录,目录名就是当前的项目名:docker_compose_blog。将刚刚生成的main文件上传到该目录下,不过需要注意这个main文件是否有可执行权限,如果没有需要使用chmod命令赋予可执行权限。并且还需要把go项目当中的config.yml配置文件上传到该目录下。然后就需要编写 Dockerfile 文件和 compose.yml 文件。其中Dockerfile文件的内容如下:

FROM golang:1.19
LABEL auth="bing" version="1.0" description="This is a blog service"
WORKDIR /app
COPY ./main /app
COPY ./config.yml /app/config/config.yml
EXPOSE 8080

Dockerfile文件写完后就需要把这个Dockerfile构建为一个镜像。如下所示:

image-20230920165753829

注意:由于当前的web服务依赖于mysql和redis的启动,所以就不能在Dockerfile文件中定义这个容器的启动命令,因此就需要我们在compose文件中定义容器的启动命令。

构建镜像的时间比较长,差不多用了5分钟。接下来就需要编写 compose.yml 文件了。compose.yml文件的内容如下所示:

services:
  mysql:
    image: mysql:8.1
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: 111
    ports:
      - 3306:3306
    volumes:
      - /root/mysql/data:/var/lib/mysql
      - /root/mysql/log:/var/log/mysql
      - /root/mysql/conf:/etc/mysql/conf.d
  redis:
    image: redis:7.0
    container_name: redis
    ports:
      - 6379:6379
    volumes:
      - /root/redis/redis.conf:/etc/redis/redis.conf
      - /root/redis/data:/data
  gin:
    build: ./
    container_name: blog
    ports:
      - 8080:8080
    volumes:
      - ./logs:/var/applogs
      - ./config.yml:/app/config/config.yml
      - ./wait-for-it.sh:/app/wait-for-it.sh
    depends_on:
      - mysql
      - redis
    command: ["./wait-for-it.sh", "mysql:3306", "--", "./wait-for-it.sh", "redis:6379","--","/app/main"]

刚开始我认为只要添加了depends_on就能让mysql和redis启动后再启动gin服务。但是后来报错了,原因是由于mysql还未完全启动,导致gin服务连接不了mysql。所以还需要一个等待其他服务启动完成的一个脚本。这个脚本就是wait-for-it.sh。它在github上就能下载到。地址:https://github.com/vishnubob/wait-for-it/blob/master/wait-for-it.sh。所以,我们要将这个脚本上传到docker_compose_blog目录下,并挂载到gin服务这个容器中(- ./wait-for-it.sh:/app/wait-for-it.sh)。下面是docker_compose_blog目录下的所有需要用到的文件:

image-20230921101855682

Compose 编排启动项目

前面就完成了所有的准备工作,现在只需要敲一些命令就行。使用docker-compose config命令可以查看我们的compose.yml文件是否有语法错误,并且加上-q选项就会只输出错误信息,没有任何消息输出就表示没有语法错误。使用docker-compose up命令就能启动所有容器,使用-d选项表示后台启动。
image-20230920173531932

接口测试

image-20230921102114648 image-20230921102148433

由于接口较多,这里就不逐个展示。

查看网络信息

使用 docker network ls命令就能查看当前docker的所有网络。可以看到使用docker compose它能创建一个网络(docker_compose_blog_default),模式为bridge。
image-20230921102447586

使用 docker network inspect docker_compose_blog_default 命令就能查看docker_compose_blog_default网络的详细信息。主要的内容如下:
image-20230921102821453

可以看到docker compose给每个服务都上传相应的容器并分配相应的IP地址,这也是为什么go项目中的config.yml配置文件中的host不需要写具体IP地址的原因。当然关于docker_compose_blog_default这个网络的名字也是可以自定义,这需要通过compose.yml文件来控制。关于docker compose的配置和命令还有很多,以后用到了在慢慢探索。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值