【docker笔记】DockerFile

DockerFile

Docker镜像结构的分层

镜像不是一个单一的文件,而是有多层构成。

容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。

如果删除了容器,也就是删除了其最上面的读写层,文件改动也就丢失了。

Docker使用存储驱动管理镜像像每层内容及可读可写的容器层

  • Dockerfile中的每个指令都会创建一个新的镜像层
  • 镜像层将被缓存和复用
  • 当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效。
  • 某一层的镜像缓存失效,它之后的镜像层缓存都会失效
  • 镜像层是不可变的,如果在某一层中添加一个文件,然后在一层中删除它,则镜像中依然会包含该文件,只是这个文件在Docker容器中不可见了

DockerFile构建过程解析

官网:https://docs.docker.com/engine/reference/builder/

构建三步骤

1、编写DockerFile文件

2、docker build命令构建镜像

3、docker run 依镜像运行容器实例

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段

Dockerfile是软件的原材料

Docker镜像是软件的交付品

Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

Docker执行DockerFile的大致流程

  1. docker从基础镜像运行一个容器
  2. 执行一条指令对容器做出修改
  3. 执行类似docker commit 的操作提交一个新的镜像层
  4. docker 在基于刚提交的镜像运行一个新容器
  5. 执行dockerfile中的下一条指令直到所有执行执行完成。

DockerFile内容基础知识

  1. 每条保留字指令都必须为大写字母且后面跟随至少一个参数
  2. 指令按照从上到下,顺序执行
  3. #表示注释
  4. 每条指令都会创建一个新的镜像层并对镜像进行提交。

DockerFile常用保留字指令

参考tomcat8的dockerfile入门

From

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

MANINTAINER

镜像维护者的姓名和邮箱地址

Run

容器构建时需要运行的命令,RUN是在docker build时运行

两种格式:

1.shell格式

<命令行命令>等同于,在终端操作的shell命令

RUN yum -y install vim

2.exec格式

EXPOSE

当前容器对外暴露出的端口

WORKDIR

指定在创建容器后。终端默认登录的进来工作目录,一个落脚点。

USER

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

ENV

用来在构建镜像过程中设置环境变量

bash 复制代码
ENV MY_PATH /usr/mytest 

这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样,

也可以在其它指令中直接使用这些环境变量, 比如:WORKDIR $MY_PATH

ADD

将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包

COPY

类似ADD,拷贝文件和目录到镜像中。

将从构建上下文目录中<源路径>的文件/目录复制到新的一层镜像内的<目标路径>位置

bash 复制代码
COPY src dest
COPY["src","dest"]
<src源路径>:源文件或源目录
<dest目标路径>: 容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

VOLUME

容器数据卷,用于数据保存和持久化的工作

CMD

指定容器启动时的要干的事情。

Dockerfile 中可以由多个CMD指令,但是只有最后一个生效,CMD会被 docker run 命令行参数中指定要运行的程序所覆盖。

他和前面RUN命令的区别 CMD 是在 docker run 时运行。 RUN 是在docker build 时运行

ENTRYPOINT

类似于CMD指令,但是ENTRYPOINT不会被docker run 后面的命令覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序

bash 复制代码
命令格式:ENTRYPOINT[" < executeable >","< param1 >","< param2 >",...]

ENTRYPOINT 可以和CMD一起用

一般是变参才会使用 CMD ,这里的CMD等于是在给 ENTRYPOINT 传参

当制定了ENTRYPOINT 后,CMD的含义就发生了变化,不再是直接运行其命令而是将 CMD 的内容作为参数传递给 ENTRYPOINT指定,他两个组合会变成< ENTRYPOINT > "< CMD >"

优点:在执行docker run 的时候可以指定 ENTRYPOINT 运行所需的参数

注意:如果Dockerfile 中如果存在多个ENTRYPOINT 指令,仅最后一个生效。

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

bash 复制代码
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参 
CMD ["/etc/nginx/nginx.conf"] # 变参 

1、不传参运行 $ docker run nginx:test

容器内会默认运行以下命令,启动主进程。

bash 复制代码
nginx -c /etc/nginx/nginx.conf 

2、传参运行 $ docker run nginx:test -c

/etc/nginx/new.conf 容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)

bash 复制代码
nginx -c /etc/nginx/new.conf

Docker之docker run参数覆盖Dockerfile中CMD命令以及CMD与ENTRYPOINT的区别

明确docker run指令中的参数是什么?

docker run 指令(-it/-p/-d等) 镜像名 参数(/bin/sh、bash等)

即docker run命令中,镜像名后面的都是给容器执行的命令参数

举例说明docker run参数覆盖Dockerfile中CMD命令的情况

举例说明docker run参数覆盖Dockerfile中ENTRYPOINT命令的情况

案例

自定义镜像mycentosjava8

要求Centos7镜像具备 vim + ifconfig + jdk8

JDK下载镜像地址

官网:https://www.oracle.com/java/technologies/downloads/#java8

https://mirrors.yangxingzhen.com/jdk/

构建Dockerfile

bash 复制代码
FROM centos
MAINTAINER mzr
  
ENV MYPATH /usr/local 
WORKDIR $MYPATH 
  
#安装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 
  
EXPOSE 80 
 
CMD echo $MYPATH 
CMD echo "success--------------ok" 
CMD /bin/bash

使用Dockerfile构建镜像

bash 复制代码
docker build -t 新镜像名字:TAG .

例如:docker build -t centosjava8:1.5 .

#【注意】上面TAG 后面有个空格,有个点

运行镜像

bash 复制代码
docker run -it 新镜像名字:TAG

例如:docker run -it centosjava8:1.5 /bin/bash

虚悬镜像

仓库名,标签都是 < none > 的镜像,俗称dangling image

构建Dockerfile

bash 复制代码
from ubuntu
CMD echo 'action is sucdess'

构建

bash 复制代码
docker build .

查看

bash 复制代码
docker image ls -f dangling=true

虚悬镜像已经失去存在价值,可以删除

bash 复制代码
docker image prune 

myubuntu

构建Dockerfile

bash 复制代码
FROM ubuntu
MAINTAINER zzyy<zzyybs@126.com> 
  
ENV MYPATH /usr/local 
WORKDIR $MYPATH 
  
RUN apt-get update 
RUN apt-get install net-tools 
#RUN apt-get install -y iproute2 
#RUN apt-get install -y inetutils-ping 
  
EXPOSE 80 
  
CMD echo $MYPATH 
CMD echo "install inconfig cmd into ubuntu success--------------ok" 
CMD /bin/bash 

使用Dockerfile构建镜像

bash 复制代码
docker build -t 新镜像名字:TAG .

例如:docker build -t myubuntu:1.0 .

#【注意】上面TAG 后面有个空格,有个点

运行镜像

bash 复制代码
docker run -it 新镜像名字:TAG

例如:docker run -it myubuntu:1.0 /bin/bash
相关推荐
桥边驿语人21 小时前
Docker 容器无法访问外网的问题排查与解决指南
运维·docker·容器
清静诗意1 天前
在 Ubuntu 上通过 Docker 与 Docker Compose 部署项目的完整指南
linux·ubuntu·docker
小Lu的开源日常1 天前
如何使用 GitHub Action 发布 Docker 镜像
docker·开源·github
神秘人X7071 天前
docker安装
docker·容器·eureka
失因1 天前
Docker 容器与镜像
java·运维·spring cloud·docker·容器
耳东哇1 天前
sentinel docker gateway k8s 集群 主从
docker·gateway·sentinel
费益洲1 天前
Docker 网络详解:(二)虚拟网络环境搭建与测试
docker·容器
郁大锤1 天前
Docker 中删除镜像与容器的完整指南
运维·docker·容器
xx.ii1 天前
docker镜像和容器
docker·容器·eureka
johnny2331 天前
Docker Desktop实战、问题记录
docker