不为有趣之事,何遣有涯之生
不失其所者久,死而不亡者寿

Docker简明教程(7) Dockerfile入门与实践技巧

Dockerfile入门与实践技巧

在上一节中演示了一个构建静态网站的例子,里面涉及到了Dockerfile的编写,刚接触的同学可能不太理解,所以专门新增一节介绍下Dockerfile的基础知识和一些编写原则与技巧。
然后以构建一个自己的java+tomcat的镜像为例子

理论部分

Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
熟悉linux下Shell脚本同学学起来应该是毫不费力,没有经验的掌握好常用的指令,多看看官网现成的例子也应该很快就上手的。

基本语法讲解

1:每条指令都必须为大写字母,且后面要跟随至少一个参数
2:指令按照从上到下,顺序执行
3:#表示注释
4:每条指令都会创建一个新的镜像层,并对镜像进行提交
5:Docker执行Dockerfile的大致流程
(1)docker从基础镜像运行一个容器
(2)执行一条指令,对容器作出修改
(3)执行类似docker commit的操作,提交一个新的镜像层
(4)docker再基于刚提交的镜像运行一个新容器
(5)执行dockerfile中的下一条指令,直到所有指令都执行完成
6:Docker会将构建镜像的过程缓存起来,如果不需要缓存,可以在docker build的时候指定 --no-cache

指令功能介绍

FROM

指定一个已经存在的镜像,也是构建的基础镜像,Dockerfile的第一条必须是FROM

MAINTAINER

设置作者,联系邮件

RUN

指定要运行的命令,建议使用数组的格式,也是exec的格式,如:
RUN[“apt-get”,”install”,”-y”,”nginx”]

EXPOSE

向容器外部公开容器内的端口

WORKDIR

指定在创建容器的时候,在容器内部设置一个工作目录,entroypoint和CMD指定的
程序会在这个目录执行
可以在docker run中使用-w来覆盖工作目录

USER

指定该镜像以什么样的用户去执行,可以单独指定用户,也可以指定用户和组,格
式:USER uid:gid,可以在docker run中通过-u来覆盖,如果都不指定,默认是root

CMD

指定一个容器启动时要运行的命令,如果指定了多条CMD,只有最后一条会执行
例如:CMD[“/bin/bash”,”-l”]
如果在docker run 后面跟上要执行的命令,会覆盖Dockerfile里面的cmd指定的命令

ENTROYPOINT

也用来指定一个容器启动时要运行命令
1:但是它不会被docker run后面的命令覆盖,而是把docker run指定的任何参数当作参数传
递给entroypoint
2:可以和CMD一起用,比如:

ENTROYPOINT[“/usr/sbin/nginx”]
CMD[“-h”]

这样如果docker run的时候不覆盖CMD,那么就是按照
/usr/sbin/nginx –h来运行
如果运行的时候:docker run –it 容器id –g“daemon off;”
那么实际运行就是:
/usr/sbin/nginx –g “daemon off;”
3:如果非要覆盖entrypoint,可以在docker run的时候,设置 --entroypoint 标志

ENV

用来在构建镜像过程中设置环境变量,例如:
ENV MY_PATH /usr/my
这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变
量前缀一样;也可以在其它指令中直接使用这些环境变量,比如:
WORKDIR $MY_PATH
可以在docker run 命令中使用–e来指定环境变量,这些变量只在运行时有效
小技巧:
可以在不需要构建缓存的前面,添加一个ENV语句,这样,要后面更新的时候,就修
改一下这个ENV的值

ADD

用来将构建环境下的文件或目录复制到镜像中。
1:只能操作构建环境相对的文件或目录,文件源也可以使用URL格式
2:如果将一个归档文件指定为源文件,docker会自动解压
3:如果目的位置不存在的话,Docker会自动创建全路径
注意:ADD会使得构建缓存无效,ADD后续指令都不能使用之前的构建缓存了

COPY

类似于ADD,COPY只做构建上下文中复制文件,而不会去做文件提取和解压的工作
如果源文件是目录,那么这整个目录会被复制到容器中

VOLUME

用来向镜像创建的容器添加卷,一个卷是可以存在于一个或者多个容器内的特定目
录,这个目录可以绕过联合文件系统,并提供如下共享数据或者对数据进行持久化:
1:卷可以在容器间共享和重用
2:对卷的修改是立即生效的
3:对卷的修改不影响镜像
卷可以让我们把数据、数据库或其它内容添加到镜像中,而不是将这些内容提交到
镜像中,并且允许我们在多个容器间共享这些内容。
注意:如果删除了最后一个使用卷的容器,内部卷就不见了。
可在docker run的时候,使用-v来把宿主机的目录映射到容器,这样数据就能一直保存了

ONBUILD

指定当镜像做为其它镜像的基础镜像时,该镜像触发执行的功能。
ONBUILD在子镜像build的时候,在FROM之后就先执行,并且只能被执行一次不会被孙镜像继承

Dockerfile编写原则

  • 容器应该是短暂的
  • 避免安装不必要的包
  • 每个容器应该只有一个关注点
  • 最小化层的数量
  • 对多行参数进行排序
  • 缓存中间构建的镜像

实践部分

编写一个Dockerfile文件

FROM ubuntu
MAINTAINER hzqiuxm
#把java与tomcat添加到容器中
ADD jdk-8u111-linux-x64.tar.gz /root/src/soft/
ADD apache-tomcat-9.0.0.M26.tar.gz /root/src/soft/
#配置java与tomcat环境变量
ENV JAVA_HOME /root/src/soft/jdk1.8.0_111
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /root/src/soft/apache-tomcat-9.0.0.M26
ENV CATALINA_BASE /root/src/soft/apache-tomcat-9.0.0.M26
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
# CMD ["/root/src/soft/apache-tomcat-9.0.0.M26/bin/catalina.sh","run"]
# ENTRYPOINT ["/root/src/soft/apache-tomcat-9.0.0.M26/bin/startup.sh" ]
CMD /root/src/soft/apache-tomcat-9.0.0.M26/bin/startup.sh && tail -F /root/src/soft/apache-tomcat-9.0.0.M26/bin/logs/catalina.out

使用Dockerfile来制作镜像
在/root/src/soft/目录下准备以下文件:1 刚创建的Dockerfile文件 2 jdk压缩包 3 tomcat压缩包,然后执行以下命令

docker build -t mytomcat9 .

构建镜像过程日志如下:

[root@localhost docker]# docker build -t mytomcat9 .
Sending build context to Docker daemon 190.8 MB
Step 1/11 : FROM ubuntu
 ---> 16508e5c265d
Step 2/11 : MAINTAINER hzqiuxm
 ---> Using cache
 ---> f5d67d9ca44a
Step 3/11 : ADD jdk-8u111-linux-x64.tar.gz /root/src/soft/
 ---> 34a20e7958ba
Removing intermediate container 8b7d6c0735ca
Step 4/11 : ADD apache-tomcat-9.0.0.M26.tar.gz /root/src/soft/
 ---> b4ce4316740b
Removing intermediate container b208617a6a63
Step 5/11 : ENV JAVA_HOME /root/src/soft/jdk1.8.0_111
 ---> Running in 1ae8272ac0ef
 ---> 52cc51e6fdcd
Removing intermediate container 1ae8272ac0ef
Step 6/11 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
 ---> Running in 91ace6986fed
 ---> a4f53b5778a4
Removing intermediate container 91ace6986fed
Step 7/11 : ENV CATALINA_HOME /root/src/soft/apache-tomcat-9.0.0.M26
 ---> Running in caf3441b162c
 ---> d1595d6ae6e7
Removing intermediate container caf3441b162c
Step 8/11 : ENV CATALINA_BASE /root/src/soft/apache-tomcat-9.0.0.M26
 ---> Running in 6e359bd47512
 ---> 23b7222d20fc
Removing intermediate container 6e359bd47512
Step 9/11 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
 ---> Running in 438a22f75079
 ---> 9c0df759c3ed
Removing intermediate container 438a22f75079
Step 10/11 : EXPOSE 8080
 ---> Running in 994985ed6196
 ---> 2bfbb442a498
Removing intermediate container 994985ed6196
Step 11/11 : CMD /root/src/soft/apache-tomcat-9.0.0.M26/bin/startup.sh && tail -F /root/src/soft/apache-tomcat-9.0.0.M26/bin/logs/catalina.out
 ---> Running in 18b045c67d53
 ---> 41bd1cf525b6
Removing intermediate container 18b045c67d53
Successfully built 41bd1cf525b6

启动容器进行测试访问

docker run -i -t -d -p 9080:8080 --name myt9 -v /ccdockermake/tomcat9/test:/root/src/soft/apache-tomcat-9.0.0.M26/webapps/test -v /tomcat9logs/:/root/src/soft/apache-tomcat-9.0.0.M26/logs --privileged=true mytomcat9

  • 可以进入运行的容器进行相关的操作
docker exec -it 容器id /bin/bash
  • 访问容器的tomcat首页
//我是在虚拟机中运行的,所以ip地址是虚拟机的地址
http://192.168.52.128:9080/

未经允许不得转载:菡萏如佳人 » Docker简明教程(7)

欢迎加入极客江湖

进入江湖关于作者