DockerFile详解

1、DockerFile基本介绍

DockerFile是用来构建Docker镜像文件,是由一系列命令和参数构成的脚本。

构建步骤:

  • 编写一个Dockerfile文件
  • docker build 构建成为一个镜像
  • docker run运行一个镜像
  • docker push 发布镜像(Docker Hub,阿里云仓库)

可以看到从Docker Hub点击某个镜像的某个版本号,进去之后看到就是Dockerfile文件,以CentOS 7为例:
在这里插入图片描述
在这里插入图片描述

2、DockerFile构建过程

基础

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

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

  • DockerFile是软件的原材料
  • Docker镜像是软件的交付品
  • Docker容器则可以认为是软件的运行态。

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

DockerFile三要素

详细解释:

  • DockerFile,需要定义一个DockerFile,DockerFile定义了进程需要的一切东西。DockerFile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这是需要考虑如何涉及namespace的权限控制)等到。
  • Docker镜像,在用DockerFile定义一个文件后,docker build会产生一个Docker镜像,当运行Docker镜像时,会真正开始提供服务。
  • Docker容器,容器直接提供服务。

3、DockerFile保留关键字

FROM			#基础镜像,当前镜像是基于哪个镜像的
MAINTAINER		#镜像作者 姓名+邮箱
RUN				#容器构建是需要运行的命令(构建镜像中执行一些命令,如Redis的DockerFile中的run命令建立用户组)
ADD				#将宿主机目录下的文件拷贝进镜像,且 ADD命令会自动处理URL和解压tar文件
COPY			#类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录<源路径>的文件/目录复制到新的一层的镜像内<目标路径>位置。
VOLUME			#容器数据卷,用于数据保存和持久化工作
CMD				#指定容器启动时要运行的命令。DockerFile中可以有多个CMD指令,但只有最后一个生效(覆盖),CMD会被docker run 之后的参数替换
ENTRYPOINT  	#指定容器启动时要运行的命令。ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序以及参数(但是不会被覆盖)
EXPOSE			#当前容器对外暴露的端口
WORKDIR     	#指定在创建容器后,终端默认登录(启动后的工作目录)进来的工作目录,一个落脚点
ENV				#用来在构建镜像过程中设置环境变量
ONBUILD     	#当构建一个被集成的DockerFile时运行命令,父镜像在被子集成后父镜像的ONBUILD被触发

补充

ENV设置环境变量:

ENV MY_PATH /usr/mytest       #设置一个环境变量

这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量,比如WORKDIR $MY_PATH #在此处使用该环境变量来指定工作目录

COPY两种写法:

COPY src desc   
COPY ["SRC","dest"]

注意:CMD会被docker run之后的参数替换

4、DockerFile案例

常见的如CentOS中都有FROM scratch,其中的scratch就是Base镜像,相当于java中的Object。

1)案例一:CentOS

默认pull下的CentOS很多命令没有而且工作目录在根目录,此处修改这些配置:

1、编写dockerfile文件

FROM centos		#基于centos构建
MAINTAINER miracle<****@qq.com>

ENV MYPATH /usr/local	#将环境遍历
WORKDIR $MYPATH			#将默认登录进来的工作目录设为MYPATH

RUN yum -y install vim		#安装yum
RUN yum -y install net-tools		#安装包含ifconfig的包

EXPOSE 80		#设置暴露的端口为80

CMD echo $MYPATH
CMD echo --------end--------
CMD /bin/bash

2、根据dockerfile文件构建镜像

#命令
docker build -f dockerfile文件路径 -t 镜像名 .

[root@Eva dockerfile]# docker build -f centos.dockerfile -t mycentos:0.1 .

3、测试运行生成的镜像,可以看看到默认的工作路径是/usr/local。而且vim和ifconfig命令都可以使用

[root@Eva dockerfile]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
mycentos             0.1                 18601a7f4f0d        2 minutes ago       317MB
[root@Eva dockerfile]# docker run -it 18601a7f4f0d bash
[root@b9c0c04dd0f1 local]# pwd
/usr/local
[root@b9c0c04dd0f1 local]# vim abc
[root@b9c0c04dd0f1 local]# ls
abc  bin  etc  games  include  lib  lib64  libexec  sbin  share  src
[root@b9c0c04dd0f1 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether 02:42:ac:12:00:06  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

使用history命令可以查看镜像构建的过程

docker history 镜像名 #查看镜像结构(历史)

在这里插入图片描述

CMD 和 ENTRYPOINT区别

CMD					# 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。
ENTRYPOINT			# 指定这个容器启动的时候要运行的命令,可以追加命令

测试CMD:

# 编写dockerfile文件
$ vim dockerfile-test-cmd
FROM centos
CMD ["ls","-a"]
# 构建镜像
$ docker build  -f dockerfile-test-cmd -t cmd-test:0.1 .
# 运行镜像
$ docker run cmd-test:0.1
.
..
.dockerenv
bin
dev

# 想追加一个命令  -l 成为ls -al
$ docker run cmd-test:0.1 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\":
 executable file not found in $PATH": unknown.
ERRO[0000] error waiting for container: context canceled 
# cmd的情况下 -l 替换了CMD["ls","-l"]。 -l  不是命令所有报错

测试ENTRYPOINT:

# 编写dockerfile文件
$ vim dockerfile-test-entrypoint
FROM centos
ENTRYPOINT ["ls","-a"]
$ docker run entrypoint-test:0.1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found ...
# 我们的命令,是直接拼接在我们得ENTRYPOINT命令后面的
$ docker run entrypoint-test:0.1 -l
total 56
drwxr-xr-x   1 root root 4096 May 16 06:32 .
drwxr-xr-x   1 root root 4096 May 16 06:32 ..
-rwxr-xr-x   1 root root    0 May 16 06:32 .dockerenv
lrwxrwxrwx   1 root root    7 May 11  2019 bin -> usr/bin
drwxr-xr-x   5 root root  340 May 16 06:32 dev
drwxr-xr-x   1 root root 4096 May 16 06:32 etc
drwxr-xr-x   2 root root 4096 May 11  2019 home
lrwxrwxrwx   1 root root    7 May 11  2019 lib -> usr/lib
lrwxrwxrwx   1 root root    9 May 11  2019 lib64 -> usr/lib64 ....

2)案例二:Tomcat

从头开始构建一个Tomcat镜像

在这里插入图片描述

1、准备镜像文件

准备tomcat 和 jdk到当前目录,编写好README

在这里插入图片描述
2、编写dockerfile文件:vim DockerFile

FROM centos
MAINTAINER Miracle42<*****@qq.com>

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u221-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.56.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

#配置java和tomcat环境遍历
ENV JAVA_HOME /usr/local/jdk1.8.2_21
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tool.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.56
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.56
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-8.5.56/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.56/bin/logs/catalina.out

3、构建镜像

docker build -f Dockerfile -t mytomcat .
#由于Dockerfile命名为Dockerfile所以也可以使用下面的命令进行构建
docker build -t mytomcat .

4、运行镜像

#将webapp挂载都宿主机
docker run -p 8080:8080 -d --name mytomcat -v /root/dockerfile/tomcat_build/webapps:/usr/local/apache-tomcat-8.5.56/webapps mytomcat

5、部署项目

在本机webapps下创建文件夹test,再创建index.html

[root@Eva webapps]# mkdir test
[root@Eva webapps]# cd test/
[root@Eva test]# vim index.html
[root@Eva test]# cat index.html 
<h1>hello world</h1>
[root@Eva test]# pwd
/root/dockerfile/tomcat_build/webapps/test
[root@Eva test]# curl localhost:8080/test/
<h1>hello world</h1>

访问 localhost:8080/test/

在这里插入图片描述

5、发布自己的镜像

1)Docker Hub

1、在Docker Hub网站上创建并登录Docker Hub

在这里插入图片描述

2、在自己服务器上登录Docker

[root@Eva test]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: miracle42
Password: 

Login Succeeded

3、将自定义镜像Push到Docker Hub

docker push mytomcat
# 可能会push不上去,因为如果没有前缀的话默认是push到 官方的library
# 解决方法
# 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了
$ docker build -t chengcoder/mytomcat:0.1 .
# 第二种 使用docker tag #然后再次push
$ docker tag 容器id chengcoder/mytomcat:1.0 #然后再次push

2)阿里云

1、注册登录阿里云

2、进入容器镜像服务

在这里插入图片描述
3、设置Registry登陆密码

4、填写相关信息创建镜像仓库

在这里插入图片描述

5、按照提示的步骤进行镜像发布

在这里插入图片描述

在这里插入图片描述

测试:

[root@Eva test]# docker login --username=miralce42 registry.cn-beijing.aliyuncs.com
Password: 
Login Succeeded

[root@Eva test]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
mytomcat             latest              f4fea7cfb67c        4 hours ago         716MB
[root@Eva test]# docker tag f4fea7cfb67c registry.cn-beijing.aliyuncs.com/miracle42/tomcat:1.0
[root@Eva test]# docker images
REPOSITORY                                           TAG                 IMAGE ID            CREATED             SIZE
registry.cn-beijing.aliyuncs.com/miracle42/tomcat    1.0                 f4fea7cfb67c        5 hours ago         716MB
[root@Eva test]# docker push registry.cn-beijing.aliyuncs.com/miracle42/tomcat:1.0
The push refers to repository [registry.cn-beijing.aliyuncs.com/miracle42/tomcat]
6c2556c201c2: Pushed 
359464d6ef75: Pushed 
823ea308519e: Pushed 
af018e0f901e: Pushed 
0683de282177: Pushed 
1.0: digest: sha256:3c5f059a96e5fcbe27213027ba2d76607820eda9c7028b2279f6675a11146452 size: 1373

接下来就可以在阿里云中看到push的镜像

在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐