image.png

构建Tomcat镜像

  1. FROM centos:7
  2. MAINTAINER zhangyingguang
  3. # 将宿主机的jdk文件拷至镜像的/usr/local目录下,会自动解压
  4. ADD jdk-8u45-linux-x64.tar.gz /usr/local
  5. # 设置环境变量
  6. ENV JAVA_HOME /usr/local/jdk1.8.0_45
  7. ADD apache-tomcat-8.0.46.tar.gz /usr/local
  8. # 拷贝文件或目录到镜像中,用法同ADD,只是不支持自动下载和解压
  9. COPY server.xml /usr/local/apache-tomcat-8.0.46/conf
  10. # 删除tar包
  11. RUN rm -rf /usr/local/*.tar.gz
  12. WORKDIR /usr/local/apache-tomcat-8.0.46
  13. # 暴露端口
  14. EXPOSE 8080
  15. # 设置启动命令
  16. ENTRYPOINT ["./bin/catalina.sh","run"]

创建镜像、创建容器

  1. docker build -t tomcat:v1 .
  2. docker run -itd --name=tomcate -p 8080:8080 \
  3. -v /app/webapps/:/usr/local/apache-tomcat-8.0.46/webapps/ \
  4. tomcat:v1

镜像优化

  1. 一次RUN指令形成新的一层,尽量Shell命令都写在一行,减少镜像层。
  2. 一次RUN形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到下一层,所以要在每一层清理对应的残留数据,减小镜像大小。
  3. 精简镜像 https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/81977225

Dockerfile关键字解释

FROM(指明构建的新镜像是来自于哪个基础镜像)
FROM centos:7

MAINTAINER(用来指定镜像创建者信息)
MAINTAINER zhangyingguang@situdata.com

RUN(安装软件用)
该指令有两种格式:
RUN [“yum”, “install”, “httpd”]
RUN yum install httpd

CMD(启动容器时执行的Shell命令)
该指令有三种格式:
CMD [“-C”, “/start.sh”]
CMD [“/usr/sbin/sshd”, “-D”]
CMD /usr/sbin/sshd -D
当Dockerfile指定了ENTRYPOINT,那么使用下面的格式:
CMD [“param1”,”param2”] (as default parameters to ENTRYPOINT)

ENTRYPOINT(启动容器时执行的Shell命令,同CMD类似,只是由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定指定的程序
两种格式:
ENTRYPOINT [“/bin/bash”, “-C”, “/start.sh”]
ENTRYPOINT /bin/bash -C ‘/start.sh’
注意:Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效。

USER(设置container容器的用户)
USER root

EXPOSE(指定容器需要映射到宿主机器的端口)
EXPOSE 80 443

ENV(用于设置环境变量)
ENV MYSQL_ROOT_PASSWORD 123456
ENV JAVA_HOME /usr/local/jdk1.8.0_45

ADD(拷贝文件或目录到镜像中)
ADD html.tar.gz /var/www/html
ADD https://xxx.com/html.tar.gz /var/www/html
注意:如果是URL或压缩包,会自动下载或自动解压。

COPY(拷贝文件或目录到镜像中,用法同ADD,只是不支持自动下载和解压)
COPY ./start.sh /start.sh

VOLUME(指定容器挂载点到宿主机自动生成的目录或其他容器))
VOLUME [“/var/lib/mysql”]
注意:一般不会在Dockerfile中用到,更常见的还是在docker run的时候指定-v数据卷。

WORKDIR(登陆容器默认目录)
WORKDIR /data

ONBUILD(在子镜像中执行)
格式: ONBUILD

补充(CMD和ENTRYPOINT的区别)

CMD(启动容器时执行的Shell命令,CMD启动的程序会被docker run命令行指定的参数所覆盖,)因为CMD命令很容易被docker run命令的方式覆盖, 所以, 如果你希望你的docker镜像的功能足够灵活, 建议在Dockerfile里调用CMD命令。

ENTRYPOINT(启动容器时执行的Shell命令,同CMD类似,只是由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT,entrypoint会把/bin/bash当成一个echo的字符串参数,不会进入到容器中。)

ENTRYPOINT的作用不同, 如果你希望你的docker镜像只执行一个具体程序, 不希望用户在执行docker run的时候随意覆盖默认程序. 建议用ENTRYPOINT.

Docker在很多情况下被用来打包一个程序. 想象你有一个用python脚本实现的程序, 你需要发布这个python程序. 如果用docker打包了这个python程序, 你的最终使用用户就不需要安装python解释器和python的库依赖,你可以把所有依赖工具打包进docker镜像里,然后用ENTRYPOINT指向你的Python脚本本身,当然你也可以用CMD命令指向Python脚本,但是通常用ENTRYPOINT可以表明你的docker镜像只是用来执行这个python脚本,也不希望最终用户用这个docker镜像做其他操作.

  1. [root@Optimus docker-training]# vim Dockerfile
  2. FROM centos:centos7.1.1503
  3. ENTRYPOINT ["/bin/echo", "This is test entrypoint"]
  4. [root@Optimus docker-training]# docker run -it csphere/ent:0.1 /bin/bash
  5. This is test entrypoint /bin/bash

注意:Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效。

组合使用
定义了 ENTRYPOINT 的话,CMD 只为 ENTRYPOINT 提供参数

  1. FROM ubuntu:trusty
  2. ENTRYPOINT ["/bin/ping","-c","3"]
  3. CMD ["localhost"]
  4. [root@Optimus docker-training]# docker run demo
  5. PING localhost (127.0.0.1) 56(84) bytes of data.
  6. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.025 ms
  7. 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.038 ms
  8. 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.051 ms
  9. --- localhost ping statistics ---
  10. 3 packets transmitted, 3 received, 0% packet loss, time 1999ms
  11. rtt min/avg/max/mdev = 0.025/0.038/0.051/0.010 ms

上面执行的命令是ENTRYPOINT和CMD指令拼接而成.,ENTRYPOINT和CMD同时存在时, docker把CMD的命令拼接到ENTRYPOINT命令之后, 拼接后的命令才是最终执行的命令. 但是由于上文说docker run命令行执行时, 可以覆盖CMD指令的值. 如果你希望这个docker镜像启动后不是ping localhost, 而是ping其他服务器,可以这样执行docker run