docker-compose 配置
文章目录
-
- 功能为指定基础镜像,并且必须是第一条指令。 如果不以任何镜像为基础,那么写法为:FROM scratch。 同时意味着接下来所写的指令将作为镜像的第一层开始 语法: FROM <image>FROM <image>:<tag>FROM <image>:<digest> 三种写法,其中<tag>和<digest> 是可选项,如果没有选择,那么默认值为latest
- 功能是为镜像指定标签 语法: LABEL <key>=<value> <key>=<value> <key>=<value> ... 一个Dockerfile种可以有多个LABEL,如下: LABEL "com.example.vendor"="ACME Incorporated"LABEL com.example.label-with-value="foo"LABEL version="1.0"LABEL description="This text illustrates \that label-values can span multiple lines." 但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用\符号如下:LABEL multi.label1="value1" \multi.label2="value2" \other="value3" RUN 功能为运行指定的命令 RUN命令有两种格式 RUN <command> RUN ["executable", "param1", "param2"] 第一种后边直接跟shell命令 在linux操作系统上默认 /bin/sh -c 在windows操作系统上默认 cmd /S /C 第二种是类似于函数调用。 可将executable理解成为可执行文件,后面就是两个参数。 事例: FROM centos:7#添加vim 操作命令RUN yum install -y vim RUN ["yum","install","-y","vim"]
- EXPOSE 功能为暴漏容器运行时的监听端口给外部 但是EXPOSE并不会使容器访问主机的端口 如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -P参数语法: EXPOSE <port>/<tcp/udp> FROM centos:7RUN yum install -y vimEXPOSE 5672EXPOSE 15672
- 语法: WORKDIR /path/to/workdir 设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次。如: WORKDIR /aWORKDIR bWORKDIR cRUN pwd pwd执行的结果是/a/b/c WORKDIR也可以解析环境变量 如: ENV DIRPATH /pathWORKDIR $DIRPATH/$DIRNAMERUN pwdpwd的执行结果是/path/$DIRNAME
- 一个复制命令,把文件复制到镜像中。 如果把虚拟机与容器想象成两台linux服务器的话,那么这个命令就类似于scp,只是scp需要加用户名和密码的权限验证,而ADD不用。 语法如下: ADD <src>... <dest>ADD ["<src>",... "<dest>"] 路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径,推荐写成绝对路径 可以是一个本地文件或者是一个本地压缩文件,还可以是一个url 如果把写成一个url,那么ADD就类似于wget命令 示例 ADD test relativeDir/ ADD test /relativeDirADD http://example.com/foobar / 注意事项 src为一个目录的时候,会自动把目录下的文件复制过去,目录本身不会复制 如果src为多个文件,dest一定要是一个目录
- 看这个名字就知道,又是一个复制命令 语法如下: COPY <src>... <dest>COPY ["<src>",... "<dest>"] 与ADD的区别 COPY的只能是本地文件,其他用法一致 FROM centos:7RUN yum install -y vimEXPOSE 5672EXPOSE 15672WORKDIR /lumenWORKDIR apiCOPY api/index.php /lumen/apiADD api/a.txt /lumen/api 执行效果如下 学习内容复习 RUN yum install -y vIm //安装vim命令EXPOSE 5672 //对外开放5672 15672两个端口EXPOSE 15672WORKDIR /data //设置工作空间 打开窗口直接进入、data/bb工作目录WORKDIR bbCOPY aa.txt /data/bb //复制文件到bb目录下ADD appche-tomcat-8.5.61.tar.gz /data/bb //将压缩包解压到bb目录下RUN mv apache-tomcat-8.5.61 tomcat //更改目录名称WORKDIR tomcat //设置工作空间 直接到tomcat目录下
- 可实现挂载功能,可以将宿主机目录挂载到容器中 说的这里大家都懂了,可用专用的文件存储当作Docker容器的数据存储部分 语法如下: VOLUME ["/data"] 说明: [/data]可以是一个JsonArray ,也可以是多个值。所以如下几种写法都是正确的VOLUME ["/var/log/"]VOLUME /var/logVOLUME /var/log /var/db 一般的使用场景为需要持久化存储数据时 容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。 所以当数据需要持久化时用这个命令。
- 功能为设置环境变量 语法有两种 ENV <key> <value>ENV <key>=<value> ... 两者的区别就是第一种是一次设置一个,第二种是一次设置多个 在Dockerfile中使用变量的方式 $varname${varname}${varname:-default value}$(varname:+default value} 第一种和第二种相同 第三种表示当变量不存在使用-号后面的值 第四种表示当变量存在时使用+号后面的值(当然不存在也是使用后面的值)
- 功能为运行指定的命令 RUN命令有两种格式 RUN <command>RUN ["executable", "param1", "param2"] 第一种后边直接跟shell命令 在linux操作系统上默认 /bin/sh -c 在windows操作系统上默认 cmd /S /C 第二种是类似于函数调用。 可将executable理解成为可执行文件,后面就是两个参数。
- 功能为容器启动时默认命令或参数 语法有三种写法 CMD ["executable","param1","param2"]CMD ["param1","param2"]CMD command param1 param2 第三种比较好理解了,就时shell这种执行方式和写法 第一种和第二种其实都是可执行文件加上参数的形式 举例说明两种写法: CMD [ "sh", "-c", "echo $HOME" CMD [ "echo", "$HOME" ] 补充细节:这里边包括参数的一定要用双引号,就是",不能是单引号。千万不能写成单引号。 原因是参数传递后,docker解析的是一个JSON array RUN&&CMD 不要把RUN和CMD搞混了。 RUN是构件容器时就运行的命令以及提交运行结果 CMD是容器启动时执行的命令,在构件时并不运行,构件时紧紧指定了这个命令到底是个什么样子
- 设置启动容器的用户,可以是用户名或UID,所以,只有下面的两种写法是正确的 USER daemoUSER UID 注意:如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行, 使用这个命令一定要确认容器中拥有这个用户,并且拥有足够权限
-
- docker-compose项目是docker官方的开源项目, 负责实现对docker容器集群的快速编排。 docker-compose将所管理的容器分为三层, 分别是工程(project),服务(service)以及容器(containner) docker-compose运行目录下的所有文件(docker-compose.yml文件、extends文件或环境变量等)组成一个工程,如无特殊指定,工程名即为当前目录名。 一个工程当中,可以包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。 一个服务中可以包括多个容器实例,docker-compose并没有解决负载均衡的问题。因此需要借助其他工具实现服务发现及负载均衡,比如consul。 docker-compose的工程配置文件默认为docker-compose.yml。可以通过环境变量COMPOSE_FILE -f 参数自定义配置文件,其自定义多个有依赖关系的服务及每个人服务运行的容器。 使用一个Dockerfile模板文件,可以让用户很方便的定义一个单独应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况,例如要实现一个web项目,除了web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。 compose允许用户通过一个单独docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器为一个项目(project) docker-compose项目由pypthon编写,调用docker服务提供的API来对容器进行管理,因此, 只要所操作的平台支持docker-API,就可以在其上利用conpose来进行编排管理。 简单来说:就是来管理多个容器的,定义启动顺序的,合理编排,方便管理 YAML文件格式 YAML是一种标记性语言,它可以很直观的展示数据序列化格式,可读性高。 类似于json数据描述语言,但是语法要比json简单很多。 YAML数据结构通过缩进来表示,连续的项目通过减号来表示,键值对用冒号分隔,数组用中括号[ ] 括起来,bash用花括号{ } 括起来。
- 不支持制表符tab键缩进,只能使用空格缩进 通常开头缩进2个空格 字符后缩进1个空格,如冒号【:】、逗号【,】、横杠【-】 用#号表示注释 如果包含特殊字符用单引号【’ '】引起来作为普通字符,如果用双引号【“ ”】表示特殊字符本身的意思, 布尔值必须用【“ ”】括起来 YAML区分大小写
- 运行这些命令需要结合docker-compose一起使用。 且必须要在含有docker-compose.yml文件的目录中才可以使用,不然报错。
- 事例:docker-compose.yml F:\lumen\docker-compose.yml version : "3.0" #docker的版本services : #服务的模块 tomcat : #服务名称 container_name: tomcat01 # 相当于run -name image : tomcat:8.0-jre8 #使用镜像名称 ports : #端口号 可以是数组 - "8080:8080" networks: - hello depends_on: #说明该服务器需要依赖mysql redis elsaticsearch 都启动才启动该服务 - mysql #书写的服务名 - redis - elsaticsearch tomcat1: container_name: tomcat02 image: tomcat:8.0-jre8 ports: - "8081:8080" volumes: # 宿主机雨容器中目录数据卷共享 - ./api:/lumen/api #自定义路径映射 - tomcatwebapps:/usr/local/tomcat/webapps networks: # 项目指定在一个网络中 - hello depends_on: - mysql - redis - elsaticsearch healthcheck: #心跳机制 test: ["CMD", "curl", "-f","http://localhost"] interval: 1m30s timeout: 10s retries: 3 # sysctls: # 用来修改容器内系统的参数 # - net.core.somaxconn:1024 # - net.ipv4.tcp_syncookies:0 ulimits: # 用来修改容器内系统最大进程数 nproc: 65535 nofile: soft: 20000 hard: 40000 mysql : container_name: mysql image : mysql:5.7.23 ports: - "3307:3306" volumes: - mysqldata:/var/lib/mysql - mysqlconf:/etc/mysql #environment: # 环境变量 如果密码比较敏感 可以使用env_file 来保存配置文件 # - MYSQL_ROOR_PASSWORD:root environment: - MYSQL_VERSION=5.6 - MYSQL_DATABASE=${MYSQL_DATABASE} - MYSQL_USER=root - MYSQL_PASSWORD=yes #- MYSQL_ROOT_PASSWcORD=${MYSQL_ROOT_PASSWORD} - MYSQL_ROOT_PASSWCORD=root - MYSQL_ALLOW_EMPTY_PASSWORD=yes - MYSQL_RANDOM_ROOT_PASSWORD=123456 networks: - hello redis : image : redis:5.0.10 container_name: redis ports: - "6380:6379" volumes: - redisdata:/data networks: - hello # command: # - "redis-server --appendonly yes" # run镜像之后覆盖容器默认命令 elsaticsearch: build: context: . #用来指定dockerfile的目录, dockerfile: Dockerfile #指定文件名 hostname: elasticsearch networks: - hellovolumes: #声明上面服务中自动创建的键名 tomcatwebapps: # 生命键名的数据卷 自动创建键名会在文件夹名会加入项目名 external : false # 使用自定义卷名 # true 确定使用卷名 mysqldata: mysqlconf: redisdata:networks: #定义服务器到网桥 hello: #定义上面使用的网桥 默认网桥为bridge external : false # 使用外部的网桥名称 如果没有该行 或者为false 则自动创建一个项目名称加上定义的网桥名称例(hello_hello) Dockerfile文件 F:\lumen\Dockerfile FROM elasticsearch:7.17.7#RUN yum install -y vimEXPOSE 5672EXPOSE 15672WORKDIR /lumenWORKDIR apiCOPY api/index.php /lumen/api
dockerfile 是镜像描述文件
通过dockerfile文件构建一个属于自己的镜像

docker包搜索镜像:https://hub.docker.com/
功能为指定基础镜像,并且必须是第一条指令。
如果不以任何镜像为基础,那么写法为:FROM scratch。
同时意味着接下来所写的指令将作为镜像的第一层开始
语法:
FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
三种写法,其中<tag>和<digest> 是可选项,如果没有选择,那么默认值为latest
功能是为镜像指定标签
语法:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
一个Dockerfile种可以有多个LABEL,如下:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用\符号如下:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
RUN
功能为运行指定的命令
RUN命令有两种格式
RUN <command>
RUN ["executable", "param1", "param2"]
第一种后边直接跟shell命令
在linux操作系统上默认 /bin/sh -c
在windows操作系统上默认 cmd /S /C
第二种是类似于函数调用。
可将executable理解成为可执行文件,后面就是两个参数。
事例:
FROM centos:7
#添加vim 操作命令
RUN yum install -y vim
RUN ["yum","install","-y","vim"]
EXPOSE
功能为暴漏容器运行时的监听端口给外部
但是EXPOSE并不会使容器访问主机的端口
如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -P参数
语法:
EXPOSE <port>/<tcp/udp>
FROM centos:7
RUN yum install -y vim
EXPOSE 5672
EXPOSE 15672
语法:
WORKDIR /path/to/workdir
设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次。如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
pwd执行的结果是/a/b/c
WORKDIR也可以解析环境变量
如:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
pwd的执行结果是/path/$DIRNAME
一个复制命令,把文件复制到镜像中。
如果把虚拟机与容器想象成两台linux服务器的话,那么这个命令就类似于scp,只是scp需要加用户名和密码的权限验证,而ADD不用。
语法如下:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径,推荐写成绝对路径
可以是一个本地文件或者是一个本地压缩文件,还可以是一个url
如果把写成一个url,那么ADD就类似于wget命令
示例
ADD test relativeDir/
ADD test /relativeDir
ADD http://example.com/foobar /
注意事项
src为一个目录的时候,会自动把目录下的文件复制过去,目录本身不会复制
如果src为多个文件,dest一定要是一个目录
看这个名字就知道,又是一个复制命令
语法如下:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
与ADD的区别
- COPY的只能是本地文件,其他用法一致
FROM centos:7
RUN yum install -y vim
EXPOSE 5672
EXPOSE 15672
WORKDIR /lumen
WORKDIR api
COPY api/index.php /lumen/api
ADD api/a.txt /lumen/api
执行效果如下

学习内容复习
RUN yum install -y vIm //安装vim命令
EXPOSE 5672 //对外开放5672 15672两个端口
EXPOSE 15672
WORKDIR /data //设置工作空间 打开窗口直接进入、data/bb工作目录
WORKDIR bb
COPY aa.txt /data/bb //复制文件到bb目录下
ADD appche-tomcat-8.5.61.tar.gz /data/bb //将压缩包解压到bb目录下
RUN mv apache-tomcat-8.5.61 tomcat //更改目录名称
WORKDIR tomcat //设置工作空间 直接到tomcat目录下
可实现挂载功能,可以将宿主机目录挂载到容器中
说的这里大家都懂了,可用专用的文件存储当作Docker容器的数据存储部分
语法如下:
VOLUME ["/data"]
说明:
[/data]可以是一个JsonArray ,也可以是多个值。所以如下几种写法都是正确的
VOLUME ["/var/log/"]
VOLUME /var/log
VOLUME /var/log /var/db
一般的使用场景为需要持久化存储数据时
容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。
所以当数据需要持久化时用这个命令。
功能为设置环境变量
语法有两种
ENV <key> <value>
ENV <key>=<value> ...
两者的区别就是第一种是一次设置一个,第二种是一次设置多个
在Dockerfile中使用变量的方式
$varname
${varname}
${varname:-default value}
$(varname:+default value}
第一种和第二种相同
第三种表示当变量不存在使用-号后面的值
第四种表示当变量存在时使用+号后面的值(当然不存在也是使用后面的值)
功能为运行指定的命令
RUN命令有两种格式
RUN <command>
RUN ["executable", "param1", "param2"]
第一种后边直接跟shell命令
在linux操作系统上默认 /bin/sh -c
在windows操作系统上默认 cmd /S /C
第二种是类似于函数调用。
可将executable理解成为可执行文件,后面就是两个参数。
功能为容器启动时默认命令或参数
语法有三种写法
CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2
第三种比较好理解了,就时shell这种执行方式和写法
第一种和第二种其实都是可执行文件加上参数的形式
举例说明两种写法:
CMD [ "sh", "-c", "echo $HOME"
CMD [ "echo", "$HOME" ]
补充细节:这里边包括参数的一定要用双引号,就是",不能是单引号。千万不能写成单引号。
原因是参数传递后,docker解析的是一个JSON array
RUN&&CMD
不要把RUN和CMD搞混了。
RUN是构件容器时就运行的命令以及提交运行结果
CMD是容器启动时执行的命令,在构件时并不运行,构件时紧紧指定了这个命令到底是个什么样子
设置启动容器的用户,可以是用户名或UID,所以,只有下面的两种写法是正确的
USER daemo
USER UID
注意:如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行,
使用这个命令一定要确认容器中拥有这个用户,并且拥有足够权限
docker-compose项目是docker官方的开源项目, 负责实现对docker容器集群的快速编排。
docker-compose将所管理的容器分为三层, 分别是工程(project),服务(service)以及容器(containner)
docker-compose运行目录下的所有文件(docker-compose.yml文件、extends文件或环境变量等)组成一个工程,如无特殊指定,工程名即为当前目录名。
一个工程当中,可以包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。
一个服务中可以包括多个容器实例,docker-compose并没有解决负载均衡的问题。因此需要借助其他工具实现服务发现及负载均衡,比如consul。
docker-compose的工程配置文件默认为docker-compose.yml。可以通过环境变量COMPOSE_FILE -f 参数自定义配置文件,其自定义多个有依赖关系的服务及每个人服务运行的容器。
使用一个Dockerfile模板文件,可以让用户很方便的定义一个单独应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况,例如要实现一个web项目,除了web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
compose允许用户通过一个单独docker-compose.yml模板文件(YAML格式)来定义一组相关联的应用容器为一个项目(project)
docker-compose项目由pypthon编写,调用docker服务提供的API来对容器进行管理,因此, 只要所操作的平台支持docker-API,就可以在其上利用conpose来进行编排管理。
简单来说:就是来管理多个容器的,定义启动顺序的,合理编排,方便管理
YAML文件格式
YAML是一种标记性语言,它可以很直观的展示数据序列化格式,可读性高。
类似于json数据描述语言,但是语法要比json简单很多。
YAML数据结构通过缩进来表示,连续的项目通过减号来表示,键值对用冒号分隔,数组用中括号[ ] 括起来,bash用花括号{ } 括起来。
不支持制表符tab键缩进,只能使用空格缩进
通常开头缩进2个空格
字符后缩进1个空格,如冒号【:】、逗号【,】、横杠【-】
用#号表示注释
如果包含特殊字符用单引号【’ '】引起来作为普通字符,如果用双引号【“ ”】表示特殊字符本身的意思,
布尔值必须用【“ ”】括起来
YAML区分大小写

运行这些命令需要结合docker-compose一起使用。
且必须要在含有docker-compose.yml文件的目录中才可以使用,不然报错。

事例:docker-compose.yml F:\lumen\docker-compose.yml
version : "3.0" #docker的版本
services : #服务的模块
tomcat : #服务名称
container_name: tomcat01 # 相当于run -name
image : tomcat:8.0-jre8 #使用镜像名称
ports : #端口号 可以是数组
- "8080:8080"
networks:
- hello
depends_on: #说明该服务器需要依赖mysql redis elsaticsearch 都启动才启动该服务
- mysql #书写的服务名
- redis
- elsaticsearch
tomcat1:
container_name: tomcat02
image: tomcat:8.0-jre8
ports:
- "8081:8080"
volumes: # 宿主机雨容器中目录数据卷共享
- ./api:/lumen/api #自定义路径映射
- tomcatwebapps:/usr/local/tomcat/webapps
networks: # 项目指定在一个网络中
- hello
depends_on:
- mysql
- redis
- elsaticsearch
healthcheck: #心跳机制
test: ["CMD", "curl", "-f","http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
# sysctls: # 用来修改容器内系统的参数
# - net.core.somaxconn:1024
# - net.ipv4.tcp_syncookies:0
ulimits: # 用来修改容器内系统最大进程数
nproc: 65535
nofile:
soft: 20000
hard: 40000
mysql :
container_name: mysql
image : mysql:5.7.23
ports:
- "3307:3306"
volumes:
- mysqldata:/var/lib/mysql
- mysqlconf:/etc/mysql
#environment: # 环境变量 如果密码比较敏感 可以使用env_file 来保存配置文件
# - MYSQL_ROOR_PASSWORD:root
environment:
- MYSQL_VERSION=5.6
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=root
- MYSQL_PASSWORD=yes
#- MYSQL_ROOT_PASSWcORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_ROOT_PASSWCORD=root
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_RANDOM_ROOT_PASSWORD=123456
networks:
- hello
redis :
image : redis:5.0.10
container_name: redis
ports:
- "6380:6379"
volumes:
- redisdata:/data
networks:
- hello
# command:
# - "redis-server --appendonly yes" # run镜像之后覆盖容器默认命令
elsaticsearch:
build:
context: . #用来指定dockerfile的目录,
dockerfile: Dockerfile #指定文件名
hostname: elasticsearch
networks:
- hello
volumes: #声明上面服务中自动创建的键名
tomcatwebapps: # 生命键名的数据卷 自动创建键名会在文件夹名会加入项目名
external : false # 使用自定义卷名 # true 确定使用卷名
mysqldata:
mysqlconf:
redisdata:
networks: #定义服务器到网桥
hello: #定义上面使用的网桥 默认网桥为bridge
external : false # 使用外部的网桥名称 如果没有该行 或者为false 则自动创建一个项目名称加上定义的网桥名称例(hello_hello)
Dockerfile文件 F:\lumen\Dockerfile
FROM elasticsearch:7.17.7
#RUN yum install -y vim
EXPOSE 5672
EXPOSE 15672
WORKDIR /lumen
WORKDIR api
COPY api/index.php /lumen/api