Dockerfile指令简介

创建Docker镜像的方式有三种
1、docker commit命令:由容器生成镜像;
2、Dockerfile文件+docker build命令;
3、从本地文件系统导入:OpenVZ的模板。

1. Dockerfile主要指令简介

Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。
一般地,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令
<br/>

基础镜像信息 FROM
维护者信息 MAINTAINER
镜像操作指令 RUN、COPY、ADD、EXPOSE等
容器启动时执行指令 CMD、ENTRYPOINT

Dockerfile文件的第一条指令必须是FROM,其后可以是各种镜像的操作指令,最后是CMD或ENTRYPOINT指定容器启动时执行的命令。

下面开始对dockerfile命令开始介绍:

FROM  

dockerfile里的第一条指令,后面跟有效的镜像名(如果该镜像你的本地仓库没有则会从远程仓库Pull取)。后面的指令在些镜像中执行。
FROM <image>:<tag>

FROM指定一个基础镜像, 一般情况下一个可用的 Dockerfile一定是 FROM 为第一个指令,至于image则可以是任何合理存在的image镜像;如果本地没有指定的镜像,则会自动从 Docker 的公共库 pull 镜像下载
FROM 一定是首个非注释指令 Dockerfile.
FROM 可以在一个 Dockerfile 中出现多次,以便于创建混合的images。
如果没有指定 tag ,latest 将会被指定为要使用的基础镜像版本。

MAINTAINER

MAINTAINER <name> 这里是用于指定镜像制作者的信息

RUN

后跟要执行的linux命令,每一条RUN指令(可能会有多条linux命令)会在当前容器最上面的可读写层执行并且提交成一个新的镜像层,接下来的指令会在这个新的镜像层里执行。

RUN <command> (the command is run in a shell – /bin/sh -c – shell form)

RUN ["executable", "param1", "param2"] (exec form)
RUN echo "Asia/Shanghai" > /etc/timezone

注意下面的情况:  
不要在一条RUN指令里单一使用apt-get update命令,这样可能会导致以后的apt-get install 安装出错。

避免使用RUN apt-get upgrade 或者dist-upgrade,这样有些重要的软件包可能更新失败,如果你确实想要更新某个包A,使用apt-get install install -y A 。这样会自动更新这个软件包。

COPY
COPY 将文件从路径 <src> 复制添加到容器内部路径 <dest>。
<src> 必须是想对于源文件夹的一个文件或目录,也可以是一个远程的url,<dest> 是目标容器中的绝对路径。
所有的新文件和文件夹都会创建UID 和 GID 。事实上如果 <src> 是一个远程文件URL,那么目标文件的权限将会是600。

ADD
ADD 将文件从路径 <src> 复制添加到容器内部路径 <dest>。
<src> 必须是想对于源文件夹的一个文件或目录,也可以是一个远程的url。<dest> 是目标容器中的绝对路径。
所有的新文件和文件夹都会创建UID 和 GID。事实上如果 <src> 是一个远程文件URL,那么目标文件的权限将会是600。

USER
USER 用来切换运行属主身份的。Docker 默认是使用 root,但若不需要,建议切换使用者身分,毕竟 root 权限太大了,使用上有安全的风险。

CMD

CMD指令指定你制作出来的镜像在启动成容器时运行命令的默认的参数。

CMD有三种写法:

CMD ["executable","param1","param2"] (exec form, this is the preferred form)

CMD ["param1","param2"] (as default parameters to ENTRYPOINT)

CMD command param1 param2 (shell form)

第一种是可执行文件加参数,第二种是作为ENTRYPOINT的参数,第三种是作为”/bin/sh -c”的参数。

注意点:
docker run命令如果指定了参数会把CMD里的参数覆盖: (这里说明一下,如:docker run -it ubuntu /bin/bash 命令的参数是指/bin/bash 而非 -it ,-it只是docker 的参数,而不是容器的参数,以下所说参数均如此。)

这里CMD与ENTRYPOINT的区别强烈推荐你去看 论docker CMD与ENTRYPOINT的大区别 http://www.cnblogs.com/programfish/p/4101884.html 这篇文章。看完你就懂了。

ENTRYPOINT

ENTRYPOINT字面意思指定容器的进入点。可以把你的容器制作成类似可执行文件的用法。这个指令会覆盖它前面的CMD指令,而多个 ENTRYPOINT指令只有最后一个生效(后面覆盖前面)。同时你也可以在在启动container 的时候指定–entrypoint参数来覆盖dockerfile里的ENTRYPOINT。详见官方文档。

例如我用了这样的指令制作镜像名叫echotest:

ENTRYPOINT ["/bin/echo"]

然后之后这样运行:

docker run -it echotest “this is a echo”

实际上是平时这样的命令:

docker run -it echotest /bin/echo “this is a echo”

这样你应该明白了吧。 这样一个容器的行为就很类似一个可执行文件了。 这里CMD与ENTRYPOINT的区别强烈推荐你去看 论docker CMD与ENTRYPOINT的大区别 http://www.cnblogs.com/programfish/p/4101884.html 这篇文章。看完你就懂了。

EXPOSE

EXPOSE指定容器对外暴露的端口号。

ENV

ENV指令可以用于为docker容器设置环境变量,例如你要确保CMD[“nginx”]能成功启动,你应该用ENV PATH /usr/local/nginx/bin:$PATH设定环境变量。另外你可以设定另外一些变量用于RUN命令里以便于dockerfile文件的维护:

ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
#设置环境变量,所有操作都是非交互式的
ENV DEBIAN_FRONTEND noninteractive

RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …

ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH

这样多次出现版本号就可以通过一个变量来管理方便维护。

VOLUME   

VOLUME ["path"] 创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保存的数据等。

为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上
FROM debian:wheezy
VOLUME /data(容器目录)

docker run -v /home/adrian/data:/data debian ls /data

WORKDIR

WORKDIR 用来切换工作目录的。Docker 默认的工作目录是/,只有 RUN 能执行 cd 命令切换目录,而且还只作用在当下下的 RUN,也就是说每一个 RUN 都是独立进行的。如果想让其他指令在指定的目录下执行,就得靠 WORKDIR。WORKDIR 动作的目录改变是持久的,不用每个指令前都使用一次 WORKDIR。

ONBUILD
ONBUILD 的作用就是让指令延迟執行,延迟到下一个使用 FROM 的 Dockerfile 在建立 image 时执行,只限延迟一次。
ONBUILD 的使用情景是在建立镜像时取得最新的源码 (搭配 RUN) 与限定系统框架

ARG
ARG是Docker1.9 版本才新加入的指令。
ARG 定义的变量只在建立 image 时有效,建立完成后变量就失效消失

LABEL
定义一个 image 标签 Owner,并赋值,其值为变量 Name 的值。(LABEL Owner=$Name )

ONBUILD
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。

例如,Dockerfile 使用如下的内容创建了镜像 image-A:
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
如果基于 image-A 创建新的镜像时,新的 Dockerfile 中使用 FROM image-A 指定基础镜像时,会自动执行 ONBUILD 指令内容,等价于在后面添加了两条指令。

2. 构建镜像

写好Dockerfile文件后就可以在该目录下运行docker build . 命令了(可以用 -t 参数指定tag)。
docker build -t centos:base .

缓存
--no-cache=true ###禁止缓存
Docker在首先检查每一条指令的时候会去cache里搜 查是否有执行过这条指令并且可以复用的镜像,如果没有再去构造一个新的镜像。这是默认的情况,如果你指定不要这个过程可以在docker build里用如下参数

3. 案例:构建tomcat镜像

###1、构建镜像可以运行tomcat的镜像环境
###2、启动容器运行tomcat程序
#################################
#1、指定基础镜像centos7
FROM openshift/base-centos7
MAINTAINER wuyan

#2、通过yum方式安装jdk1.8
RUN yum install java -y

#3、将本地tomcat程序添加到容器中
RUN mkdir -p /ghca/
ADD apache-tomcat-7.0.75 /ghca/apache-tomcat-7.0.75
RUN chmod -R 775 /ghca

#ADD start_tomcat.sh /ghca/start_tomcat.sh
#RUN chmod 775 /ghca/start_tomcat.sh

#4、配置tomcat环境变量
ENV CATALINA_HOME /ghca/apache-tomcat-7.0.75
ENV PATH $PATH:$CATALINA_HOME/bin

#5、容器端口配置
EXPOSE 8090
#6、启动tomcat
CMD /ghca/start_tomcat.sh && tail -f /ghca/apache-tomcat-7.0.75/logs/catalina.out

<<完毕>>

猜你喜欢

转载自blog.51cto.com/chbinmile/2124539