跳至主要內容

Docker

yyshino大约 28 分钟

Docker快速入门

Docker常用命令 | Dockerfile构建镜像 | docker-compose构建多容器项目

docker
docker

应用容器

基本介绍

  • 什么是应用容器

我们可以把它看成虚拟机,能在一台服务器上隔离出若干个互不干扰的环境。把自己的应用放入容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。它具有启动快、资源占用少、体积小、易操作等等。相比虚拟机有很多优势。

  • 为什么要使用应用容器

因为软件更新发布及部署低效,过程繁琐且需要人工介入。环境一致性难以保证,不同环境之间迁移成本太高。有了应用容器部署可以很大程度解决上面的问题。

  • Docker 应用容器部署

Docker是一个开源的应用容器引擎,目前有三大类。

(1)提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。

(2)提供弹性的云服务。因为Docker容器可以随开随关,很适合动态扩容和缩容。

(3)组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构

安装下载

  • Mac

在 Mac | 上安装码头工人文档 (docker.com)open in new window

  • Windows

在 Windows | 上安装码头工人文档 (docker.com)open in new window

  • Linux

在 Linux | 上安装码头工人文档 (docker.com)open in new window

配置镜像

由于国内外网络问题,我们需要配置国内镜像源,提高拉去速度。

  • 阿里云镜像

访问 容器镜像服务 (aliyun.com)open in new window 获取你的阿里云镜像

    {
      "registry-mirrors": ["https://nrxbdvhi.mirror.aliyuncs.com"]
    }

Linux

使用配置文件/etc/docker/daemon.json(没有时新建该文件)。

    vim /etc/docker/daemon.json
    # 添加如下内容,可以自己替换。默认地址是我的创建的
    {
      "registry-mirrors": ["https://mr63yffu.mirror.aliyuncs.com"]
    }

重启Docker Daemon即可。

    systemctl daemon-reload

Windows

在如图所示位置添加配置镜像

添加配置镜像
添加配置镜像

架构概念

通过下图可以得知,Docker在运行时分为Docker引擎(服务端守护进程)客户端工具,我们日常使用各种docker命令,其实就是在使用客户端工具Docker引擎进行交互。

docker
docker

Client 客户端

Docker是一个客户端-服务器(C/S)架构程序。Docker客户端只需要向Docker服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。Docker提供了一个命令行工具Docker以及一整套RESTful API。你可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。

Host 主机(Docker 引擎)

一个物理或者虚拟的机器用于执行Docker守护进程和容器。

Image 镜像

什么是Docker镜像?简单的理解,Docker镜像就是一个Linux文件系统(Root FileSystem),这个文件系统里面包含可以运行在Linux内核的程序以及相应的数据。

通过镜像启动一个容器,一个镜像就是一个可执行的包,其中包括运行应用程序所需要的所有内容:包含代码,运行时间,库,环境变量和配置文件等。

Docker 把 App 文件打包成为一个镜像,并且采用类似多次快照的存储技术,可以实现:

  • 多个App可以共用相同的底层镜像(初始的操作系统镜像);
  • App运行时的IO操作和镜像文件隔离;
  • 通过挂载包含不同配置/数据文件的目录或者卷(Volume),单个App镜像可以用来运行无数个不同业务的容器。

Container 容器

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

Docker面向对象
镜像
容器对象

像分层

Docker 支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的。

docker
docker

从上图可以看到,新镜像是从base镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层。

镜像分层最大的一个好处就是共享资源。比如说有多个镜像都从相同的base镜像构建而来,那么Docker Host只需在磁盘上保存一份base镜像;同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

如果多个容器共享一份基础镜像,当某个容器修改了基础镜像的内容,比如/etc下的文件,这时其他容器的/etc是不会被修改的,修改只会被限制在单个容器内。这就是容器Copy-on-Write特性。

Volume 数据卷

实际上我们的容器就好像是一个简易版的操作系统,只不过系统中只安装了我们的程序运行所需要的环境,前边说到我们的容器是可以删除的,那如果删除了,容器中的程序产生的需要持久化的数据怎么办呢?容器运行的时候我们可以进容器去查看,容器一旦删除就什么都没有了。

所以数据卷就是来解决这个问题的,是用来将数据持久化到我们宿主机上,与容器间实现数据共享,简单的说就是将宿主机的目录映射到容器中的目录,应用程序在容器中的目录读写数据会同步到宿主机上,这样容器产生的数据就可以持久化了,比如我们的数据库容器,就可以把数据存储到我们宿主机上的真实磁盘中。

注册中心Registry 注册中心

DockerRegistry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营公共的Registry叫做Docker Hub。用户可以在Docker Hub注册账号,分享并保存自己的镜像。

Docker公司提供了公共的镜像仓库https://hub.docker.com(Docker 称之为 Repository)提供了庞大的镜像集合供使用。

一个Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签对应该软件的各个版本。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以latest作为默认标签。

alibaba-docker
alibaba-docker

镜像命令

官方文档:https://docs.docker.com/reference

查看镜像

执行命令:docker images

属性说明
REPOSITORY镜像在仓库中的名称
TAG镜像标签
IMAGE ID镜像 ID
CREATED镜像的创建日期
SIZE镜像大小

这些镜像都是存储在Docker宿主机的/var/lib/docker目录下。

搜索镜像

如果你需要从网络中查找需要的镜像,可以通过以下命令搜索。

执行命令:docker search 镜像名称

属性说明
NAME镜像名称
DESCRIPTION镜像描述
STARS用户评价
OFFICIAL是否为官方构建
AUTOMATEDDocker Hub 自动构建

拉取镜像

拉取镜像就是从中央仓库下载镜像到本地。

执行命令:docker pull 镜像名称

如果不声明tag镜像标签信息则默认拉取latest版本。

删除镜像

按镜像ID删除单个镜像。

执行命令:docker rmi 镜像ID

按镜像ID删除多个镜像。

执行命令:docker rmi 镜像ID 镜像ID 镜像ID

docker images -q可以查询到所有镜像的ID,通过组合命令可以实现删除所有镜像的操作。

执行命令:docker rmi docker images -q

::: Tips

注意:如果通过某个镜像创建了容器,则该镜像无法删除。 解决办法:先删除镜像中的容器,再删除该镜像。

:::

容器命令

查看容器

容器命令描述
docker ps查看正在运行的容器。
docker ps -f status=exited查看停止的容器。
docker ps -a查看所有容器(包括运行和停止)。
docker ps -l查看最后一次运行的容器。
docker ps -n 5列出最近创建的 n 个容器。

概念介绍

属性说明
CONTAINER ID容器 ID
IMAGE所属镜像
COMMAND启动容器时运行的命令
CREATED创建时间
STATUS容器状态
PORTS端口
NAMES容器名称

创建与启动容器

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

容器命令说明
docker run -it --name 容器名称 镜像名称:标签 /bin/bash表示运行容器

创建并进入容器

docker run -it --name 容器名称 镜像名称:标签 /bin/bash

容器命令说明
CONTAINER ID容器 ID
IMAGE所属镜像
COMMAND启动容器时运行的命令
CREATED创建时间
STATUS容器状态
PORTS端口
NAMES容器名称

其他命令

容器命令说明
exit退出当前容器
docker run -di --name 容器名称 镜像名称:标签守护式方式创建容器
`docker exec -it 容器名称容器ID /bin/bash`
`docker stop 容器名称容器ID`
`docker start 容器名称容器ID`

文件拷贝

容器命令说明
docker cp 需要拷贝的文件或目录 容器名称:容器目录将文件拷贝到容器内
docker cp 容器名称:容器目录 需要拷贝的文件或目录将文件从容器内拷贝出来

目录挂载

我们可以在创建容器的时候,将宿主机的目录与容器内的目录进行映射,这样我们就可以通过修改宿主机某个目录的文件从而去影响容器,而且这个操作是双向绑定的,也就是说容器内的操作也会影响到宿主机,实现备份功能。

但是容器被删除的时候,宿主机的内容并不会被删除。如果多个容器挂载同一个目录,其中一个容器被删除,其他容器的内容也不会受到影响。

创建容器添加-v参数,格式为宿主机目录:容器目录,例如:

    docker run -di -v /home/ruoyi/data:/usr/local/data --name centos7-01 centos:7

    # 多目录挂载
    docker run -di -v /宿主机目录:/容器目录 -v /宿主机目录2:/容器目录2 镜像名

::: Tips

目录挂载操作可能会出现权限不足的提示。这是因为CentOS7中的安全模块SELinux把权限禁掉了,在docker run时通过--privileged=true给该容器加权限来解决挂载的目录没有权限的问题。

:::

容器命令说明
docker run -di -v /usr/local/data --name centos7-02 centos:7匿名挂载只需要写容器目录即可,容器外对应的目录会在/var/lib/docker/volumes中生成。
docker run -di -v docker_centos_data:/usr/local/data --name centos7-03 centos:7具名挂载就是给数据卷起了个名字,容器外对应的目录会在/var/lib/docker/volume中生成。
docker run -di -v /宿主机目录:/容器目录 -v /宿主机目录2:/容器目录2 镜像名指定目录挂载 之前挂载方式就属于指定目录挂载,这种方式的挂载不会在/var/lib/docker/volume目录生成内容
docker volume ls查看 volume 数据卷信息
docker volume inspect 数据卷名称可以查看该数据卷对应宿主机的目录地址
docker inspect 容器ID或名称在返回的JSON节点中找到Mounts,可以查看详细的数据挂载信息
docker run -it -v /宿主机目录:/容器目录:ro 镜像名只读。只能通过修改宿主机内容实现对容器的数据管理。
docker run -it -v /宿主机目录:/容器目录:rw 镜像名读写,默认。宿主机和容器可以双向操作数据。

删除容器

容器命令说明
`docker rm 容器名称容器ID`
`docker rm 容器名称容器ID 容器名称

查看容器 IP 地址


# 容器命令                                                     说明
docker inspect 容器名称|容器ID                             # 查看容器的元信息
docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称|容器ID` # 直接输出 IP 地址

应用部署

Nacos

Nacos部署命令说明
docker pull nacos/nacos-server拉取官方nacos镜像
docker run --env MODE=standalone --name nacos -d -p 8848:8848 nacos/nacos-server启动nacos
  • MODE=standalone表示单机启动

Nginx

拉取官方nginx镜像

执行命令:docker pull nginx

创建Nginx容器。

    docker run -di --name nginx -p 80:80 nginx

将容器内的配置文件拷贝到指定目录(请先提前创建好目录)。

    # 创建目录
    mkdir -p /home/ruoyi/nginx

    # 将容器内的配置文件拷贝到指定目录
    docker cp nginx:/etc/nginx /home/ruoyi/nginx/conf

终止并删除容器

    docker stop nginx
    docker rm nginx

创建Nginx容器,并将容器中的/etc/nginx目录和宿主机的/home/ruoyi/nginx/conf目录进行挂载。

    docker run -di --name nginx -p 80:80 -v /home/ruoyi/nginx/conf:/etc/nginx nginx

Mysql

拉取官方mysql5.7镜像

执行命令:docker pull mysql:5.7

  • 创建容器

在本地创建mysql的映射目录

    mkdir -p /home/mysql/data /home/mysql/logs /home/mysql/conf

创建容器,将数据、日志、配置文件映射到本机

    docker run -p 3306:3306 --name mysql -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/logs:/logs -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password -d mysql:5.7
  • -d: 后台运行容器
  • -p 将容器的端口映射到本机的端口
  • -v 将主机目录挂载到容器的目录
  • -e 设置参数

进入容器/执行命令:docker exec -it mysql /bin/bash

Redis

拉取官方redis镜像

执行命令:docker pull redis

创建容器。

    docker run -di --name redis -p 6379:6379 redis

连接容器中的Redis时,只需要连接宿主机的IP + 指定的映射端口即可。

镜像构建

Docker 支持自己构建镜像,还支持将自己构建的镜像上传至公共仓库

容器命令说明
docker commit从容器创建一个新的镜像
docker build配合Dockerfile文件创建镜像

示例

接下来我们通过基础镜像centos:7,在该镜像中安装jdktomcat以后将其制作为一个新的镜像mycentos:7

创建镜像

    # 拉取镜像
    docker pull centos:7

    # 创建容器
    docker run -di --name centos7 centos:7

拷贝资源

    # 将宿主机的jdk和tocat拷贝至容器
    docker cp jdk-8u111-linux-x64.tar.gz centos7:/root

    docker cp apache-tomcat-8.5.27.tar.gz centos7:/root

安装资源

    # 进入容器
    docker exec -it centos7 /bin/bash

    # 切换至 /root目录
    cd root/

    # 创建java和tomcat目录
    mkdir -p /usr/local/java
    mkdir -p /usr/local/tomcat

    # 将jdk和tomcat解压至容器 /usr/local/java 和 /usr/local/tomcat/
    tar -zxvf jdk-8u111-linux-x64.tar.gz -C /usr/local/java/
    tar -axvf apache-tomcat-8.5.27.gz -C /usr/local/tomcat/

    # 配置jdk环境变量
    vi /etc/profile

    # 在环境变量文件中添加以下内容
    export JAVA_HOME = /usr/local/java/jdk1.8.0_111/
    export PATH = $PATH:$JAVA_HOME/bin

    # 重新加载环境变量文件
    source /etc/profile

    # 测试环境变量是否配置成功
    java -version

    # 删除容器内 jdk和 tomcat
    rm jdk-8u111-linux-x64.tar.gz apache-tomcat-8.5.27.tar.gz -rf

构建镜像

    docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
    docker commit -a="ruoyi" -m="jdk8 and tomcat8" centos7 mycentos:7
  • -a:提交的镜像作者;
  • -c:使用 Dockerfile 指令来创建镜像;
  • -m:提交时的说明文字;
  • -p:在 commit 时,将容器暂停。

使用构建的镜像创建容器

    # 创建容器
    docker run -di --name mycentos7 -p 8080:8080 mycentos:7

    # 进入容器
    docker exec -it mycentos7 /bin/bash

    # 重新加载配置文件
    source /etc/profile

    # 测试java环境变量
    java -version

    # 启动 tomcat
    /usr/local/tomcat/apache-tomcat-8.5.27/bin/startup.sh
    # 访问http://{ip}:{port},看到tomcat页面说明环境表示成功

Dockerfile

Docker中构建镜像最常用的方式,就是使用DockerfileDockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。官方文档:https://docs.docker.com/engine/reference/builder

Dockerfile 常用指令

指令语法说明
FROMFROM <image>:<tag>指明构建的新镜像是来自于哪个基础镜像,如果没有选择tag,那么默认值为latest
MAINTAINERMAINTAINER <name>指明镜像维护者及其联系方式(一般是邮箱地址)。官方说明已过时,推荐使用LABEL
LABELLABEL <key>=<value> ...功能是为镜像指定标签。也可以使用LABEL来指定镜像作者
RUNRUN <command>构建镜像时运行的Shell命令,比如构建的新镜像中我们想在/usr/local目录下创建一个java目录
ADDADD <src>... <dest>拷贝文件或目录到镜像中。src 可以是一个本地文件,还可以是一个url。然后自动下载和解压
COPYCOPY <src>... <dest>拷贝文件或目录到镜像中。用法同 ADD,只是不支持自动下载和解压
EXPOSEEXPOSE <port> [<port>/<protocol>...]暴露容器运行时的监听端口给外部,可以指定端口是监听 TCP 还是 UDP,如果未指定协议,则默认为 TCP
ENVENV <key>=<value> ...设置容器内环境变量
CMDCMD ["executable","param1","param2"]启动容器时执行的Shell命令。在Dockerfile中只能有一条CMD指令。如果设置了多条CMD,只有最后一条会生效
ENTRYPOINTENTRYPOINT ["executable", "param1", "param2"]启动容器时执行的 Shell 命令,同 CMD 类似,不会被 docker run 命令行指定的参数所覆盖,如果设置了多条ENTRYPOINT,只有最后一条会生效
WORKDIRWORKDIR param为 RUN、CMD、ENTRYPOINT 以及 COPY 和 AND 设置工作目录
VOLUMEVOLUME ["param"]指定容器挂载点到宿主机自动生成的目录或其他容器。一般的使用场景为需要持久化存储数据时

构建镜像

Dockerfile文件编写好以后,真正构建镜像时需要通过docker build命令。

docker build命令用于使用Dockerfile创建镜像。

    # 使用当前目录的 Dockerfile 创建镜像
    docker build -t mycentos:7 .

    # 通过 -f Dockerfile 文件的位置创建镜像
    docker build -f /home/ruoyi/docker/Dockerfile -t mycentos:7 .
Dockerfile实践

接下来我们通过基础镜像centos:7,在该镜像中安装jdktomcat以后将其制作为一个新的镜像mycentos:7

创建目录,编写Dockerfile文件

    mkdir -p /usr/local/`dockerfile`

执行命令:vi Dockerfile,写入信息

    # 指明构建的新镜像是来自于`centos:7`基础镜像
    FROM centos:7
    # 通过镜像标签声明了作者信息
    LABEL maintainer = "ruoyi.vip"

    # 设置工作目录
    WORKDIR /usr/local
    # 新镜像构建成功以后创建指定目录
    RUN mkdir -p /usr/local/java && mkdir - p /usr/local/tomcat
    # 拷贝文件到镜像中并解压
    ADD jdk-8u111-linux-x64.tar.gz /usr/local/java
    ADD apache-tomcat-8.5.27.tar.gz /usr/local/tomcat
    # 暴露容器运行时的8080监听端口给外部
    EXPOSE 8080
    # 设置容器内 JAVA_HOME 环境变量
    ENV JAVA_HOME /usr/local/java/jdk1.8.0_111
    ENV PATH:$JAVA_HOME/bin
    # 启动容器时启动tomcat
    CMD ["/usr/local/tomcat/apache-tomcat-8.5.27/bin/catalina.sh", "run"]

构建镜像

    docker build -f /home/ruoyi/docker/Dockerfile -t mycentos:test .

启动镜像

    docker run -di --name mycentos -p 8080:8080 mycentos:test

进入容器

    docker exec -it mycentos7 /bin/bash
镜像构建历史

docker history 镜像名称:标签|ID

    docker history mycentos:7

镜像仓库

我们使用的镜像都是从DockerHub公共仓库拉取的,我们也学习了如何制作自己的镜像,但是通过tar包的方式实现镜像的备份恢复迁移对于团队协作开发并不是特别友好,我们也可以将镜像推送至DockerHub仓库方便使用。

温馨提示:如果构建的镜像内携带了项目数据,建议还是使用私有仓库比较好。

注册账号

官网 Docker Hub 官网open in new window

登录账号

docker login

推送镜像至仓库

    docker tag hello-world:latest ruoyivip/test-hello-world:1.0.0
    docker push ruoyivip/test-hello-world:1.0.0

查看仓库

Docker Hubopen in new window

拉取镜像

通过docker pull ruoyivip/test-hello-world:1.0.0测试镜像是否可以拉取。

退出账号

通过docker logout退出账号

Docker Compose

通过前面几篇文章的学习,我们可以通过Dockerfile文件让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况,或者开发一个Web应用,除了Web服务容器本身,还需要数据库服务容器、缓存容器,甚至还包括负载均衡容器等等。

Docker Compose恰好满足了这样的需求,它是用于定义和运行多容器Docker应用程序的工具。通过Compose,您可以使用YAML文件来配置应用程序所需要的服务。然后使用一个命令,就可以通过YAML配置文件创建并启动所有服务。

Docker Compose项目是Docker官方的开源项目,来源于之前的Fig项目,使用Python语言编写。负责实现对Docker容器集群的快速编排。项目地址为:https://github.com/docker/compose/releases

Docker Compose使用的三个步骤为:

  • 使用Dockerfile文件定义应用程序的环境;
  • 使用docker-compose.yml文件定义构成应用程序的服务,这样它们可以在隔离环境中一起运行;
  • 执行docker-compose up命令来创建并启动所有服务。

Compose安装

Overview | Docker Documentationopen in new window

docker-compose.yml 文件详解

官方文档:https://docs.docker.com/compose/compose-file/

Docker Compose允许用户通过docker-compose.yml文件(YAML 格式)来定义一组相关联的容器为一个工程(project)。一个工程包含多个服务(service),每个服务中定义了创建容器时所需的镜像、参数、依赖等。

Docker Compose模板文件我们需要关注的顶级配置有versionservicesnetworksvolumes几个部分,除version外,其他几个顶级配置下还有很多下级配置,后面也会详细给大家介绍,先来看看这几个顶级配置都什么意思:

  • version:描述Compose文件的版本信息,当前最新版本为3.8,对应的Docker版本为19.03.0+
  • services:定义服务,可以多个,每个服务中定义了创建容器时所需的镜像、参数、依赖等
  • networkds:定义网络,可以多个,根据DNS server让相同网络中的容器可以直接通过容器名称进行通信
  • volumes:数据卷,用于实现目录挂载
示例
    # 描述 Compose 文件的版本信息
    version: "3.8"

    # 定义服务,可以多个
    services:
        nginx: # 服务名称
            image: nginx # 创建容器时所需的镜像
            contaainer_name: mynginx # 容器名称,默认为"工程名称_服务条目名称_序号"
            ports: # 宿主机与容器的端口映射关系
                - "80:80" # 左边宿主机端口:右边容器端口
            networks: # 配置容器连接的网络,引用顶级 networks 下的条目
                - nginx-net

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

使用docker-compose up创建并启动所有服务

    # 前台启动
    docker-compose up

    # 后台启动
    docker-compose up -d

浏览器访问:http://192.168.10.10/ 结果如下

使用docker-compose down可以停止并删除容器、网络。

version 版本信息

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

Compose file formatDocker Engine release
3.819.03.0+
3.718.06.0+
3.618.02.0+
3.517.12.0+
3.417.09.0+
3.317.06.0+
3.217.04.0+
3.11.13.1+
3.01.13.0+
...1.x.x
services 定义服务

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

比如,通过docker run命令构建一个MySQL应用容器的命令如下:

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

使用ocker-compose.yml以后则可以这样定义:

    version: "3.8"
    # 定义服务,可以多个
    services:
        mysql: # 服务名称
            image: mysql:8 # 创建容器时所需的镜像
            container_name: mysql8 # 容器名称,默认为"工程名称_服务条目名称_序号"
            posts: # 宿主机遇容器的端口映射关系
                - "3306:3306" # 左边宿主机端口:右边容器端口
            environment: # 创建容器时所需的环境变量
                MYSQL_ROOT_PASSWORD: 1234
            volumes:
                - "/mydata/docker_mysql/conf:/etc/mysql/conf.d"
                - "/mydata/docker_mysql/data:/var/lib/mysql"

image镜像名称标签

指定创建容器时所需的镜像名称标签或者镜像ID。如果镜像在本地不存在,会去远程拉取。

    services:
        web:
            image: hello-world
build构建容器

除了可以基于指定的镜像构建容器,还可以基于Dockerfile文件构建,在使用up命令时会执行构建任务

context文件路径

该选项可以是Dockerfile文件的绝对/相对路径,也可以是远程Git仓库的URL,当提供的值是相对路径时,相对当前docker-compose.yml文件所在目录。

    build:
        context: . # 相对当前 docker-compose.yml 文件所在目录, 基于名称为 Dockerfile文件构建镜像
dockerfile构建镜像

一般情况下,默认都基于文件名叫Dockerfile的文件构建镜像,当然也可以是自定义的文件名,使用dockerfile声明,不过这个选项只能声明文件名,文件所在路径还是要通过centext来声明

    build:
        context: . # 相对当前docker-compose.yml 文件多种目录
        dockerfile: Dockerfile-alternate # 基于名称为Dockerfile-alternate 的文件构建镜像
container_name容器名称

Compose创建的容器默认生成的名称格式为:工程名称_服务条目名称_序号。如果要使用自定义名称,使用container_name声明

    services:
        mycentos:
            build: .
            container_name: mycentos7 # 容器名称,默认为"工程名称_服务条目名称_序号"

因为Docker容器名称必须是唯一的,所有如果指定了自定义名称,就不能将服务扩展至多个容器。这样做可能会导致错误。

depend_on 容器依赖

使用Compose最大的好处就是敲最少的命令做更多的事情,但一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。例如在没有启动数据库容器的情况下启动了Web应用容器,应用容器会因为找不到数据库而退出。depends_on就是用来解决容器依赖、启动先后问题的配置项

    version: "3.8"

    services:
        web:
            build: .
            depends_on:
                - db
                - redis
            redis:
                image: redis
            db:
                image: mysql

上述YAML文件定义的容器会先启动dbredis两个服务,最后才启动web服务

ports暴露端口

容器对外暴露的端口, 格式: 坐标宿主机端口:右边容器端口

    ports:
        - "8080"
        - "8080:8080
expose接受端口范围

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

    expose:
        - "80"
        - "8080"
restart重启策略

容器重启策略, 简单的理解就是Docker 重启以后容器要不要一起启动

  • no: 默认的重启策略,在任何情况下都不会重启容器;
  • no-failure: 容器非正常退出是,比如退出状态为非0(异常退出),才会重启容器
  • always: 容器总是重新启动,即使容器被手动停止了,当Docker重启时容器也还是会一起启动;
  • unless-stopped: 容器总是重新启动, 除非容器被停止 (手动或其他方式), 那么Docker重启时容器则不会启动
    services:
        nginx:
            image: nginx
            container_name: mynginx
            posts:
                - "80:80"
            restart: always
environment环境变量

添加环境变量。可以使用数组也可以使用字典。布尔相关的值(true、false、yes、no)都需要用引号括起来,以确保 YML 解析器不会将它们转换为真或假

    environment:
        RUOYI_ENV: development
        SHOW: "true"
        SESSION_SECRET:

或者一下格式

    environment:
        - RUOYI_ENV=development
        - SHOW=true
        - SESSION_SECRET

env_file文件获取环境变量

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

    env_file:
        - /opt/runtime_opts.env # 绝对路径
        - ./common.env # 相对路径,相对当前 docker-compose.yml 文件所在目录
        - ./apps/web.env # 相对路径,相对当前 docker-compose.yml 文件所在目录

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

command执行命令

覆盖容器启动后默认执行的命令

    command: echo "helloworld"

该命令也可以是一个列表

    command: ["echo","helloworld"]
volumes目录挂载

数据卷,用于实现目录挂载,支持指定目录挂载、匿名挂载、具名挂载。

  • 指定目录挂载的格式为:左边宿主机目录:右边容器目录,或者左边宿主机目录:右边容器目录:读写权限;
  • 匿名挂载格式为:容器目录即可,或者容器目录即可:读写权限;
  • 具名挂载格式为:数据卷条目名称:容器目录,或者数据卷条目名称:容器目录:读写权限。
# 描述 Compose文件的版本信息
version: "3.8"

# 定义服务,可以多个
serveices:
	mysql: #服务名称
		image: mysql:8 # 创建容器所需的镜像
		container_name: mysql8 # 容器名称,默认为"工程名称_服务条目名称_序号"
		ports: # 宿主机与容器的端口:右边容器端口
			- "3306:3306" # 左边宿主机端口:右边容器端口
		environment: # 创建容器时所需要的环境变量
			MYSQL_ROOT_PASSWORD: 1234
		volumes:
			# 绝对路径
			- "/mydata/docker_mysql/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
aliases

网络上此服务的别名。同一网络上的其他容器可以使用服务名或此别名连接到服务容器。同一服务在不同的网络上可以具有不同的别名。

    # 定义服务,可以多个
    services:
      nginx: # 服务名称
        networks: # 配置容器连接的网络,引用顶级 networks 下的条目
          nginx-net: # 一个具体网络的条目名称
            aliases: # 服务别名,可以多个
              - nginx1 # 同一网络上的其他容器可以使用服务名或此别名连接到服务容器

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

Compose常用命令

Commands:
  build              # 构建或重新构建服务
  create             # 创建服务
  up                 # 创建并启动所有服务的容器。指定多个yml加-f选项。以守护进程模式运行加-d选项。
  down               # 停止并删除所有服务的容器、网络、镜像、数据卷
  pull               # 拉取服务依赖的镜像
  push               # 推送服务图片
  start              # 启动服务容器
  stop               # 停止服务容器
  top                # 显示正在运行的进程
  pause              # 暂停服务容器
  unpause            # 恢复服务容器。
  events             # 从容器接收实时事件
  exec               # 进入服务容器
  help               # 查看帮助
  images             # 打印服务容器所对应的镜像
  kill               # 通过发送SIGKILL信号停止指定服务的容器。
  logs               # 查看服务容器的输出日志
  port               # 打印指定服务容器的某个端口所映射的宿主机端口
  ps                 # 列出工程中所有服务的容器
  restart            # 重启服务容器
  rm                 # 删除服务(停止状态)容器
  run                # 列出工程中所有服务的容器
  scale              # 设置服务的容器数
  version            # 显示Docker Compose版本信息
  bundle             # 从compose中生成一个Docker包
  config             # 验证并查看Compose文件,docker-compose config -q验证docker-compose.yml文件。当配置正确时,不输出任何内容,当配置错误时,输出错误信息

参考

码头工人桌面|码头工人文档 (docker.com)open in new window

应用容器部署 | RuoYiopen in new window

Reference documentation | Docker Documentationopen in new window

Dockerfile reference | Docker Documentationopen in new window

Docker Hub Container Image Library | App Containerizationopen in new window