Docker学习之docker-compose详解

Docker学习之docker-compose详解

通过前面两篇的学习,我们可以通过 Dockerfile 文件让用户很方便的定义一个单独的应用容器。

然后,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。

开发一个 web应用,除了web服务器本身,还需要数据库容器、缓存容器、可能还需要一些负载均衡容器等等。

Docker-compose 介绍

Docker compose 恰好满足这样的需求,它是用于「定义和运行多容器 Docker 应用程序」 的工具。

通过Compose,我们可以使用YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

Docker compose 使用的三个步骤:

  • 使用 Dockerfile 文件定义应用程序的环境

  • 使用 docker compose 编排所有服务

  • 最后使用 docker-compose up(v1) 或者 docker compose up(v2) 进行创建并启动所有服务。

Docker compose 中的概念:

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

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

docker-compose.yml 文件详解

Docker compose 允许用户通过 docker-compose.yml 文件来定义一组相关联的容器为一个工程。

模板文件是使用 Compose 的核心,涉及很多指令关键字。

version

描述 Compose 文件的版本信息,当前最新版本为 3.8,对应的 Docker 版本为 19.03.0+。关于每个版本的详细信息请参考:https://docs.docker.com/compose/compose-file/compose-versioning/

以下为 Compose 文件的版本信息所对应的 Docker 版本。

Docker学习之docker-compose详解
compose文件版本对应特定docker版本

services

services 用来定义服务,可以多个,每个服务中定义了创建容器时所需要的镜像、参数、依赖等,就像将命令行参数传递给 docker run 一样。

使用docker run 构建一个MySQL容器:

docker run -di --name think_mysql8 -p 3306:3306 -v /mydata/mysql/conf:/etc/mysql/conf.d -v /mydata/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:8

使用 docker-compose.yml 定义为:

# 描述 compose 文件的版本
version: "3.8"

# 定义服务,可以多个
services:
  # 服务名
  mysql:
    # 所使用的镜像
    image: mysql:8
    
    # 容器名称
    container_name: think_mysql8
    
    # 宿主机和容器的端口映射关系
    ports:
      - "3306:3306"
    
    # 创建容器需要的环境变量
    MYSQL_ROOT_PASSWORD: 123456
    
    # 挂载卷
    - "/mydata/mysql/conf:/etc/mysql/conf.d"
    - "/mydata/mysql/data:/var/lib/mysql"

image

指定创建容器时所需要的 镜像名称tag 或者 镜像ID, 镜像本地不存在, 则会去docker hub 上进行拉取

services:
  nginx:
    image: nginx:latest

build

基于 Dockerfile 文件进行构建, 在使用 docker-compose up 时会进行构建。

通过 build 配置项可以指定 Dockerfile 所在文件夹的路径。Compose 将会利用 Dockerfile 自动构建镜像,然后使用镜像启动服务容器。

# 绝对路径,在该路径下基于名称为 Dockerfile 的文件构建镜像
/var/data/my-docker

# 相对路径,相对当前 docker-compose.yml 文件所在目录,基于名称为 Dockerfile 的文件构建镜像
.

version: "3.8"
services:
  webapp:
    build: ./dir

使用context指令指定dockerfile所在文件夹的路径, 也可以是远程 Git 仓库的 URL

使用dockerfile指令指定dockerfile文件名

使用arg指令指定构建镜像时的变量

version: "3.8"
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-web
      args:
        buildno: 1

container_name

Compose 创建的容器默认生成的名称格式为: 工程名称_服务名称_序号, 想使用自定义名称的话, 使用 container_name 关键字声明。

services:
  webapp:
    container_name: think/webapp

depends_on

一般项目容器启动顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。

例如,在没有启动数据库容器而启动了web容器,web容器因找不到数据库而退出。

depends_on 就是解决容器依赖,启动先后顺序的问题。

version:"3.8"
  services:
    web:
      build: .
      depends_on:
        - db
        - redis
        
    redis:
      image: redis
      
    db:
      image: mysql

这时会先启动 db, redis 在启动 web 服务。

ports

容器对外暴露的端口, 映射到宿主机上。

使用宿主端口:容器端口 (HOST:CONTAINER) 格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。

ports:
  - "80:80"
  - "3306:3306"

tips:当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML 会自动解析 xx:yy 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。

expose

容器暴露的端口不映射到宿主机, 只允许能被连接的服务访问。

expose:
  - "80"
  - "8080"

restart

容器重启策略,简单理解就是 Docker 重启以后容器要不要一起启动。配置有以下几种方式:

  • no: 默认的重启策略,在任何情况下都不会重启容器;

  • no-failure:容器非正常退出时,才会重启容器;

  • always: 容器总是重新启动,即使容器被手动停止了, 当Docker重启时容器也会一起启动。

  • unless-stopped: 容器总是重新启动, 除非容器被停止(手动或者其他方式), 那么Docker 重启时则不会启动。

services:
  nginx:
    image: nginx
    container_name: mynginx
    ports:
      - "80:80"
    restart: always

environment

环境变量。可以使用数组或者字典,布尔相关的值都需要使用引号括起来,包括以下:

y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF

确保YAML解析器不会将他们转换为真或假。

# 第一种方式
environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:
  
# 第二种方式
environment:
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET

env_file

从文件中获取环境变量, 可以指定一个或多个文件,优先级低于environment 指定的环境变量。

evn_file:
  - /var/php.env     # 绝对路径
  - ./php.env        # 相对路径, 相对当前 docker-compose.yml 文件所在目录
  - ./apps/mysql.env # 相对路径, 相对当前 docker-compose.yml 文件所在目录

tips: env文件的每一行采用 键=值 的方式。以 # 开头的行会被视为注释并被忽略。空行也会被忽略。

volumes

数据卷所挂载路径设置。数据卷,用于实现目录挂载,支持「指定目录挂载」、「匿名挂载」、「具名挂载」

  • 指定目录挂载: 宿主机目录 : 容器目录 : 读写权限(可省略)

  • 匿名挂载: 容器目录:读写权限(可忽略)

  • 具名挂载: 数据卷条目名称:容器目录:读写权限(可忽略)

version: "3.8"

# 定义服务,可以多个
services:
  mysql: # 服务名称
    image: mysql:8 # 创建容器时所需的镜像
    container_name: mysql8 # 容器名称,默认为"工程名称_服务条目名称_序号"
    ports: # 宿主机与容器的端口映射关系
      - "3306:3306" # 左边宿主机端口:右边容器端口
    environment: # 创建容器时所需的环境变量
      MYSQL_ROOT_PASSWORD: 1234
    volumes:
      # 绝对路径
      - "/mydata/docker/data:/var/lib/mysql"
      # 相对路径,相对当前 docker-compose.yml 文件所在目录
      - “./conf:/etc/mysql/conf.d“
      # 匿名挂载,匿名挂载只需要写容器目录即可,容器外对应的目录会在 /var/lib/docker/volume 中生成
      - "/var/lib/mysql"
      # 具名挂载,就是给数据卷起了个名字,容器外对应的目录会在 /var/lib/docker/volume 中生成
      - "mysql-data-volume:/var/lib/mysql"

# 定义数据卷,可以多个
volumes:
  mysql-data-volume: # 一个具体数据卷的条目名称
    name: mysql-data-volume # 数据卷名称,默认为"工程名称_数据卷条目名称"

network_mode

设置网络模式, 类似 docker run 时添加的参数 –net host 或者 –network host 的用法。

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

networks

配置容器连接的网络,引用顶级 networks 下的条目。

# 定义服务,可以多个
services:
  nginx: # 服务名称
    networks: # 配置容器连接的网络,引用顶级 networks 下的条目
      - nginx-net # 一个具体网络的条目名称

# 定义网络,可以多个。如果不声明,默认会创建一个网络名称为"工程名称_default"的 bridge 网络
networks:
  nginx-net: # 一个具体网络的条目名称
    name: nginx-net # 网络名称,默认为"工程名称_网络条目名称"
    driver: bridge # 网络模式,默认为 bridge

compose 命令详解

V1版本: docker-compose [-f <arg> ...] [options] [command] [args...]

V2版本: docker compose [-f <arg> ...] [options] [command] [args...]
  • -f, –file: 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定,指定多个 yml;

  • -p, –project-name:指定工程名称,默认使用 docker-compose.yml 文件所在目录的名称;

  • -v:打印版本并退出;

  • –log-level:定义日志等级(DEBUG, INFO, WARNING, ERROR, CRITICAL)。

config

验证 docker-compose.yml 文件是否正确, 正确时不输出任何内容; 错误时,输出错误信息。

docker compose config -q 

pull

docker-compose pull 拉取服务依赖的镜像。

# 拉取工程中所有服务依赖的镜像
docker-compose pull
# 拉取工程中 nginx 服务依赖的镜像
docker-compose pull nginx
# 拉取镜像过程中不打印拉取进度信息
docker-compose pull -q

up

docker-compose up 创建并启动所有服务的容器。指定多个 yml 加 -f 选项。以守护进程模式运行加 -d 选项。

# 前台启动
docker-compose up
# 后台启动
docker-compose up -d
# -f 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定,指定多个 yml
docker-compose -f docker-compose.yml up -d 

logs

docker-compose logs 查看服务容器的输出日志。默认情况下,docker-compose 将对不同的服务输出使用不同的颜色来区分。可以通过 –no-color 来关闭颜色。

# 输出日志,不同的服务输出使用不同的颜色来区分
docker-compose logs
# 跟踪日志输出
docker-compose logs -f
# 关闭颜色
docker-compose logs --no-color

exec

docker-compose exec 进入服务容器。

# 进入工程中指定服务的容器
docker-compose exec nginx bash
# 当一个服务拥有多个容器时,可通过 --index 参数进入到该服务下的任何容器
docker-compose exec --index=1 nginx bash

pause

docker-compose pause 暂停服务容器。

# 暂停工程中所有服务的容器
docker-compose pause
# 暂停工程中指定服务的容器
docker-compose pause nginx

unpause

docker-compose unpause 恢复服务容器。

# 恢复工程中所有服务的容器
docker-compose unpause
# 恢复工程中指定服务的容器
docker-compose unpause nginx

restart

docker-compose restart 重启服务容器。

# 重启工程中所有服务的容器
docker-compose restart
# 重启工程中指定服务的容器
docker-compose restart nginx

start

docker-compose start 启动服务容器。

# 启动工程中所有服务的容器
docker-compose start
# 启动工程中指定服务的容器
docker-compose start nginx

stop

docker-compose stop 停止服务容器。

# 停止工程中所有服务的容器
docker-compose stop
# 停止工程中指定服务的容器
docker-compose stop nginx

kill

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

# 通过发送 SIGKILL 信号停止工程中指定服务的容器
docker-compose kill nginx

rm

docker-compose rm 删除服务(停止状态)容器。

# 删除所有(停止状态)服务的容器
docker-compose rm
# 先停止所有服务的容器,再删除所有服务的容器
docker-compose rm -s
# 不询问是否删除,直接删除
docker-compose rm -f
# 删除服务容器挂载的数据卷
docker-compose rm -v
# 删除工程中指定服务的容器
docker-compose rm -sv nginx

images

docker-compose images 打印服务容器所对应的镜像。

# 打印所有服务的容器所对应的镜像
docker-compose images
# 打印指定服务的容器所对应的镜像
docker-compose images nginx

port

docker-compose port 打印指定服务容器的某个端口所映射的宿主机端口。

[root@localhost docker-nginx]# docker-compose port nginx 80
0.0.0.0:80

top

docker-compose top 显示正在运行的进程。

# 显示工程中所有服务的容器正在运行的进程
docker-compose top
# 显示工程中指定服务的容器正在运行的进程
docker-compose top nginx

docker的运行原理,会在下一篇文章中输出,欢迎各位大佬评论留言讨论。

如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我继续坚持下去,非常感谢!

你还可以把我的公众号设为「星标」,这样当公众号文章更新时,你会在第一时间收到推送消息,避免错过我的文章更新。

原文始发于微信公众号(白砂):Docker学习之docker-compose详解

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/19988.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!