在Centos Stream 9上Docker的实操教程(五) - Dockerfile详解

在Centos Stream 9上Docker的实操教程 - Dockerfile详解

  • 回忆我们之前的构建
  • Dockerfile是干什么的
    • 先看一个Dockerfile例子
    • 尝试构建镜像
  • Dockerfile的常用指令
    • FORM指令
    • RUN指令
    • ADD指令
    • COPY指令
    • ENV指令
    • VOLUME指令
    • WORKDIR指令
    • CMD指令
    • ENTRYPOINT指令
    • EXPOSE指令
    • USER指令
    • LABEL指令
  • 实操编写Centos7默认具备JDK8的镜像
  • 结语

回忆我们之前的构建

再没了解Dockerfile之前,假设我们docker需要运行一个centos容器,并且该容器需要安装部署redis、mysql、jdk等要求,我们之前的做法:

#拉取镜像
docker pull centos:7
#运行镜像
docker run -d centos:7
#进入容器
docker exec -it XXX镜像ID /bin/bash
#通过yum安装所需
yum install -y redis
#等等操作

以上是我们之前docker的操作方式,那么有没有一种可以直接一次性帮我们将这些命令都汇总起来,一次性执行呢? dcoker官方也考虑到了点,那就是使用我们的Dockerfile

Dockerfile是干什么的

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。Docker通过读取 Dockerfile可以快速构建我们所需的镜像。
官方的文档地址: https://docs.docker.com/engine/reference/builder/

先看一个Dockerfile例子

#必须FROM开头指定镜像模版
FROM centos:7 
#定义环境变量
ENV MYPATH /usr/local
#设置工作目录
WORKDIR $MYPATH
#指定作者
LABEL org.opencontainers.image.authors="micro"
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
CMD echo "success"
CMD /bin/bash

通过上面的命令,其实就是以centos为基础镜像,指定了工作目录(进入容器后默认进入该目录),并在原centos镜像基础上安装了vim、ifconfig命令,生成一个新的镜像

尝试构建镜像

我大家可以复制上述Dockerfile指令来演示一下,首先按照博主之前设置的data目录,创建一个myfile文件夹用来存放我们本次的Dockerfile

#创建目录
mkdir /data/myfile
#进入目录
cd  /data/myfile
#复制上述例子内容
vim Dockerfile
#构建镜像 注意语法后面有一个 .
docker build -t mycentos:1.0 .

注:最后的 . 代表本次执行的上下文路径,上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包

相信大家已经构建出了自己新的centos镜像,默认的centos镜像是不存在 vim 和 ifconfig 指令的,可以run起来测试一下指令是否生效。

Dockerfile的常用指令

FORM指令

基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是FORM

FROM centos:7 

RUN指令

执行后面跟着的命令行命令,有两种格式:

第一种shell格式:(常用)
# <命令行命令> 等同于,在终端操作的 shell 命令。
RUN <命令行命令>
#如
RUN yum -y install vim

第二种exec格式:
RUN ["可执行文件", "参数1", "参数2"]

ADD指令

将宿主机中目录的文件拷贝到镜像,如果拷贝的是压缩文件会自动解压;

#将jdk 拷贝到镜像/usr/local/java/ 并解压
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/

COPY指令

从上下文目录中复制文件或者目录到容器里指定路径,和ADD指令类似,区别就在于COPY指令不会帮我们解压;

ENV指令

用来在构建镜像过程中设置环境变量,如Dockerfile例子中,定义了MYPATH,后续的指令中可以通过 $MYPATH 引用

#定义环境变量
ENV MYPATH /usr/local
#设置工作目录
WORKDIR $MYPATH

VOLUME指令

容器数据匿名卷,用于数据保存和持久化工作,并不然,VOLUME指令只是起到了声明了容器中的目录作为匿名卷,但是并没有将匿名卷绑定到宿主机指定目录的功能。

注意不要认为和 -v 挂载数据卷作用一样,VOLUME指令并没有将匿名卷绑定到宿主机指定目录的功能,VOLUME只是指定了一个目录,用以在用户忘记启动时指定-v参数也可以保证容器的正常运行。

VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>

WORKDIR指令

设定工作目录,用户登陆进入容器后默认的工作路径

CMD指令

CMD指令和RUN指令类似,但他们也有区别;

CMD 在docker run 时运行
RUN 在 docker build 时运行
如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效
CMD 会被 docker run 之后的参数替换

CMD <shell 命令> 
CMD ["<可执行文件或命令>","","",...] 
# 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
CMD ["","",...]

ENTRYPOINT指令

ENTRYPOINT指令也是用来指定一个容器启动时要运行的命令,类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序

语法格式

ENTRYPOINT ["","","",...]
  • ENTRYPOINT可以和CMD一起用,一般是变参才会使用 CMD,这里的 CMD 等于是在给 ENTRYPOINT 传参

  • 当指定了ENTRYPOINT后,CMD就不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令

  • 如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效

FROM nginx

ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参这里定义 newnginx.conf

假设已通过 Dockerfile 构建了 nginx:test 镜像:

命令 不传参运行 传参运行
docker命令 docker run nginx:test docker run nginx:test -c /etc/nginx/new.conf
生成容器内运行命令 nginx -c /etc/nginx/nginx.conf nginx -c /etc/nginx/new.conf

经过上述演示,ENTRYPOINT 指令可以在执行 docker run 的时候可以指定运行所需的某些参数,从而无需一定传参运行

EXPOSE指令

当前容器对外暴露出的端口,当 docker run -P 的时候容器会自动随机映射 EXPOSE 的端口

USER指令

指定该镜像以什么样的用户去执行,如果都不指定默认是root

USER <用户名>[:<用户组>]

LABEL指令

LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式,语法格式如下:

LABEL <key>=<value> <key>=<value> <key>=<value> ...
# 比如我们可以添加镜像的作者
LABEL org.opencontainers.image.authors="micro"

实操编写Centos7默认具备JDK8的镜像

首先为了演示各指令用法,我们下载官网下载一个压缩包的jdk这里下载 jdk-8u171-linux-x64.tar.gz , 改造我们的Dockerfile例子

一切准备完成后 在Dockerfile相同目录下应该具备以下文件:
Dockerfile
jdk-8u171-linux-x64.tar.gz

FROM centos:7 
#定义环境变量
ENV MYPATH /usr/local
#设置工作目录
WORKDIR $MYPATH
#指定作者
LABEL org.opencontainers.image.authors="micro"
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools

#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

CMD echo "success"
CMD /bin/bash

完成Dockerfile文件编写,我们执行构建命令试试吧

docker build -t mycentos:1.1 .

结语

本章节主要介绍了Dockerfile的用法以及Dockerfile的常用指令,大家可以根据自己的需求自由编写自己的Dockerfile文件进行测试,如果本章节内容对你有用,希望点赞收藏加关注,谢谢!

下一章:在Centos Stream 9上Docker的实操教程 - Docker Compose容器编排详解

你可能感兴趣的:(Docker,docker,centos,linux)