docker-compose 配置

时间:2021-06-16 00:41:12

dockerfile 是镜像描述文件

通过dockerfile文件构建一个属于自己的镜像

docker-compose 配置

docker包搜索镜像:​​https://hub.docker.com/​

1 指令介绍

1.1 FROM 镜像

功能为指定基础镜像,并且必须是第一条指令。

如果不以任何镜像为基础,那么写法为:FROM scratch。

同时意味着接下来所写的指令将作为镜像的第一层开始

语法:

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>
三种写法,其中<tag><digest> 是可选项,如果没有选择,那么默认值为latest


1.2 LABEL

功能是为镜像指定标签

语法:

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"]

1.3 EXPOSE 端口

EXPOSE

功能为暴漏容器运行时的监听端口给外部

但是EXPOSE并不会使容器访问主机的端口

如果想使得容器与主机的端口有映射关系,必须在容器启动的时候加上 -P参数
语法:

EXPOSE <port>/<tcp/udp>
FROM centos:7
RUN yum install -y vim
EXPOSE 5672
EXPOSE 15672

1.4 WORKDIR 工作空間

语法:

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

1.5 ADD 添加

一个复制命令,把文件复制到镜像中。

如果把虚拟机与容器想象成两台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一定要是一个目录


1.6 COPY 复制文件

看这个名字就知道,又是一个复制命令

语法如下:

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

执行效果如下

docker-compose 配置

学习内容复习

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目录下

1.7 VOLUME 挂载目录

可实现挂载功能,可以将宿主机目录挂载到容器中

说的这里大家都懂了,可用专用的文件存储当作Docker容器的数据存储部分

语法如下:

VOLUME ["/data"]

说明:

[/data]可以是一个JsonArray ,也可以是多个值。所以如下几种写法都是正确的
VOLUME ["/var/log/"]
VOLUME /var/log
VOLUME /var/log /var/db

一般的使用场景为需要持久化存储数据时

容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,所有的更改都会丢失。

所以当数据需要持久化时用这个命令。

1.8 ENV 环境变量

功能为设置环境变量

语法有两种

ENV <key> <value>
ENV <key>=<value> ...

两者的区别就是第一种是一次设置一个,第二种是一次设置多个

在Dockerfile中使用变量的方式

$varname
${varname}
${varname:-default value}
$(varname:+default value}

第一种和第二种相同

第三种表示当变量不存在使用-号后面的值

第四种表示当变量存在时使用+号后面的值(当然不存在也是使用后面的值)

1.9 RUN 命令执行

功能为运行指定的命令

RUN命令有两种格式

RUN <command>
RUN ["executable", "param1", "param2"]

第一种后边直接跟shell命令

在linux操作系统上默认 /bin/sh -c

在windows操作系统上默认 cmd /S /C

第二种是类似于函数调用。

可将executable理解成为可执行文件,后面就是两个参数。


1.9 CMD 命令执行

功能为容器启动时默认命令或参数

语法有三种写法

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是容器启动时执行的命令,在构件时并不运行,构件时紧紧指定了这个命令到底是个什么样子

1.10 USER 启动用户

设置启动容器的用户,可以是用户名或UID,所以,只有下面的两种写法是正确的

USER daemo
USER UID

注意:如果设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行,

使用这个命令一定要确认容器中拥有这个用户,并且拥有足够权限


2 docker-compose 

2.1 compose

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用花括号{ } 括起来。

2.2、YAML格式的注意事项

不支持制表符tab键缩进,只能使用空格缩进

通常开头缩进2个空格

字符后缩进1个空格,如冒号【:】、逗号【,】、横杠【-】

用#号表示注释

如果包含特殊字符用单引号【’ '】引起来作为普通字符,如果用双引号【“ ”】表示特殊字符本身的意思,

布尔值必须用【“ ”】括起来

YAML区分大小写

docker-compose 配置

2.3、Docker-compose常用命令

运行这些命令需要结合docker-compose一起使用。

且必须要在含有docker-compose.yml文件的目录中才可以使用,不然报错。

docker-compose 配置

3 事例分析

事例: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