Dockerfile-指令详解(附:tomcat+jdk dockerfile)

Dockerfile 简单一点就是描述你这个镜像安装了哪些软件包,有哪些操作,创建了什么东西。有些人喜欢用docker commit 命令去打包镜像,这样是不好的,首先commit出来的镜像比你使用Dockerfile构建出来的体积大,而且commit出来的镜像属于黑盒镜像,除了制作者,谁都不知道你在里面干了什么,属于不安全的镜像,很少会有人使用,最后就是不便于你最终的管理和更新。所以推荐使用Dockerfile去管理你的镜像,下面将简单介绍Dockerfile常见的指令和注意事项:

FROM
FROM命令是指定你所使用的基础镜像,一般写在文件开头,如果想自定义构建docker镜像,那么引用的基础镜像一般是:centos,debian,ubuntu 等等。

指令语法:

FROM <image>
FROM <image>:<tag>
FROM <image>:<digest>

eg:
FROM 镜像ID(不建议使用镜像ID,如果在镜像比较多的情况下容易混淆)

FROM debian:jessie
FROM centos:v1
FROM ubuntu:16.04
FROM mysql:5.7
FROM python:2.7

MAINTAINER:
MAINTAINER命令一般描述这个Dockerfile的作者信息

指令语法:

MAINTAINER <name>

eg:

MAINTAINER YinYiHang <17600077230@163.com>

RUN:
运行指定的命令,此命令只有在执行docker build 时才会执行,其他情况下不会执行。这时候有很多初学者会以为在写SHELL,那么在一个Dockerfile里面会出现很多不合理的RUN指令,Docker的镜像是分层结构,说白了就是Dockerfile里面一个指令的操作就是一层。比如下面的操作,一条RUN命令包含了更新源缓存,安装openjdk,清理垃圾,这样的好处是最终这一层会很小,假设你分开写,三个命令三个RUN指令,但是只有第二条命令才是你想要的,那么第一条产生的缓存垃圾就无法删除掉。这也算是docker镜像优化的一部分。

指令语法:

这里只写第一种格式,有兴趣的朋友可以去官网看看其他的方式

RUN <command>

eg:

RUN yum update \
&& yum install openjdk-8-jdk  -y \
&& yum clean all 

尽量合并层级

实例1:

RUN apt-get update \
&& apt-get install axel --no-install-recommends -y \
&& axel -n 20 --output=/usr/local/src/zookeeper-${ZOOKEEPER_VERSION}.tar.gz http://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-${ZOOKEEPER_VERSION}/zookeeper-${ZOOKEEPER_VERSION}.tar.gz \
&& tar -zxf /usr/local/src/zookeeper-${ZOOKEEPER_VERSION}.tar.gz -C /usr/local/ \
&& rm -rf /usr/local/src/zookeeper-${ZOOKEEPER_VERSION}.tar.gz \
&& apt-get remove axel -y \
&& apt-get clean all \
&& rm -rf /var/lib/apt/lists/*

实例2:

RUN apt-get update \
RUN apt-get install axel --no-install-recommends -y
RUN axel -n 20 --output=/usr/local/src/zookeeper-${ZOOKEEPER_VERSION}.tar.gz http://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-${ZOOKEEPER_VERSION}/zookeeper-${ZOOKEEPER_VERSION}.tar.gz
RUN tar -zxf /usr/local/src/zookeeper-${ZOOKEEPER_VERSION}.tar.gz -C /usr/local/
RUN rm -rf /usr/local/src/zookeeper-${ZOOKEEPER_VERSION}.tar.gz
RUN apt-get remove axel -y
RUN apt-get clean all
RUN rm -rf /var/lib/apt/lists/*

实例1为合并层级,实例2为没有合并的,实例2中最后4行相当于没执行。为什么这样呢,因为每次你RUN的时候是在新的层级上面,而不是你想删除的地方。

CMD:
设置容器启动时要运行的命令只有在你执行 docker run 或者 docker start 命令是才会运行,其他情况下不运行。如果一个Dockerfile里面有多条CMD指令,那么只有文件最后一行的 CMD 指令才会生效,其他的全部没用,还有一点,还有一点 CMD指令是可以在你执行 docker run 的时候覆盖的。此命令必须是前台运行!!!

指令语法:

CMD ["nginx"]

EXPOSE:
设置暴露端口号,注意是容器暴露端口号,并不是暴露到物理机上的端口号!!

指令语法:

EXPOSE port

eg:

EXPOSE  80

ENV:
功能为设置环境变量,此环节变量可以是在构建镜像时使用,也可以在运行中的容器使用。

指令语法

ENV <key> <value>

eg:
一种写法

ENV JAVA_HOME /usr/lib/jvm/java-7-openjdk-amd64
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH $PATH:$JAVA_HOME/bin:$JRE_HOME/bin

另一种写法

ENV JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64 \
CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar \
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin

ADD:
复制命令,把本机的文件复制到镜像中,如果dest是目录则会帮你自动创建出这个目录,如果src是压缩文件会帮你自动压缩出来,当然ADD指令中的src也可以是URL的链接,还有另外一条指令 COPY ,注意区别!!!

另外, src部分是是你Dockerfile的相对路径,这个请注意!!!

指令语法:

ADD <src> <dest>

eg:

ADD nginx.conf /etc/nginx/nginx.conf
ADD app.tar.gz /app/app

COPY:
与ADD指令类似但是COPY的src部分只能是本地文件,文件路径是Dockerfile的相对路径。如果COPY的是压缩包不会帮你解压。

指令语法:

COPY <src> <dest>

eg:

COPY app.tar.gz /app

VLOUME:
设置你的卷,在启动容器的时候Docker会在/var/lib/docker/的下一级目录下创建一个卷,以保存你在容器中产生的数据。若没有申明则不会创建。(可以把此指令看成shell中的mkdir)此指令不是独立数据卷,数据会随着容器的停止而消失,如果想数据持久化,请参考docker 简单命令 在run启动容器是加-V 参数!

指令语法:

VOLUME ["/path/to/directory"]

eg:

VOLUME ["/data/"]
VOLUME ["/data","/data/etc"]

WORKDIR:
指定容器的工作目录,可以在构建镜像的时候使用,也可以在启动容器的时候使用,构建使用是通过WORKDIR将当前目录切换到指顶目录中,可以理解为shell的cd,启动容器的时候使用的意思为 docker run 启动容器时,默认进入到目录是WORKDIR 指定的。

指令语法:

WORKDIR /path/to/workdir

eg:

WORKDIR /usr/local/nginx

以下是一个安装tomcat+jdk的dockerfile

引用一个centos为基础镜像

FROM centos:v1

制作者:YinYiHang

MAINTAINER YinYiHang

将tomcat和jdk压缩包复制到/usr/local下

ADD jdk-8u60-linux-x64.tar.gz /usr/local
ADD apache-tomcat-6.0.53.tar.gz /usr/local

设置jdk的环境变量相当于更改/etc/profile文件

ENV JAVA_HOME /usr/local/jdk1.8.0_60
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME=/usr/local/apache-tomcat-6.0.53
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

暴露容器端口为8080

EXPOSE 8080

在docker run 的时候执行catalina.sh 来启动tomcat

CMD ["catalina.sh","run"]
Logo

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

更多推荐