Docker Compose

文章目录

    • 简介
    • compose文件
      • [一、 文件简介](#一、 文件简介)
      • [二、 version](#二、 version)
      • [三、 services](#三、 services)
        • [1. build:](#1. build:)
        • [2. image](#2. image)
        • [3. container_name](#3. container_name)
        • [4. ports](#4. ports)
        • [5. command](#5. command)
        • [6. depends_on](#6. depends_on)
        • [7. deploy](#7. deploy)
        • [8. networks](#8. networks)
        • [9. volumes](#9. volumes)
      • [四、 networks](#四、 networks)
        • [1. name](#1. name)
        • [2. driver](#2. driver)
        • [3. attachable](#3. attachable)
      • 五、volumes
    • 常用命令
    • 项目搭建
    • [Compose 编排启动项目](#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 属性指定文件名++。

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

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

yaml 复制代码
services:
  mysqlDB:
  	image: mysql:8.0
3. container_name

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

yaml 复制代码
services:
  mysqlDB:
  	image: mysql:8.0
  	container_name: mysql_container
4. ports

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

yaml 复制代码
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两种语法。

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

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

yaml 复制代码
services:
  mysqlDB:
  	image: mysql:8.0
  	depends_on: 
  	  - nginx
  	  - initConf
7. deploy

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

yaml 复制代码
services:
  mysqlDB:
    image: mysql:8.0
    deploy:
      mode: replicated
      replicas: 6
8. networks

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

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

需要注意以下几点:

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

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

yaml 复制代码
services:
  mysqlDB:
    image: mysql:8.0
    volumes: 
      - /etc/mysql:/var/lib/mysql

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

yaml 复制代码
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属性,那么网络将直接使用这个名称,而不是默认的名称。

yaml 复制代码
networks:
  mynetwork:
    name: my_custom_network

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

2. driver

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

3. attachable

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

yaml 复制代码
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代码,所以需要使用交叉编译的方式生成一个项目的可执行文件。操作截图如下:

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

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构建为一个镜像。如下所示:

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

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

yaml 复制代码
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目录下的所有需要用到的文件:

Compose 编排启动项目

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

接口测试

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

查看网络信息

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

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

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

相关推荐
好奇的菜鸟10 分钟前
Docker 配置项详解与示例
运维·docker·容器
xcs1940537 分钟前
集运维 麒麟桌面版v10 sp1 2403 aarch64 离线java开发环境自动化安装
运维·自动化
BAOYUCompany40 分钟前
暴雨服务器成功中标华中科技大学集成电路学院服务器采购项目
运维·服务器
超龄超能程序猿1 小时前
Bitvisse SSH Client 安装配置文档
运维·ssh·github
奈斯ing2 小时前
【Redis篇】数据库架构演进中Redis缓存的技术必然性—高并发场景下穿透、击穿、雪崩的体系化解决方案
运维·redis·缓存·数据库架构
鳄鱼皮坡2 小时前
仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器
运维·服务器
即将头秃的程序媛2 小时前
centos 7.9安装tomcat,并实现开机自启
linux·运维·centos
小Mie不吃饭3 小时前
FastAPI 小白教程:从入门级到实战(源码教程)
运维·服务器
fo安方4 小时前
运维的利器–监控–zabbix–第三步:配置zabbix–中间件–Tomcat–步骤+验证
运维·中间件·zabbix
超喜欢下雨天4 小时前
服务器安装 ros2时遇到底层库依赖冲突的问题
linux·运维·服务器·ros2