利用Dockerfile创建镜像

Dockfile是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令。Docker程序将这些Dockerfile指令翻译真正的Linux命令。Dockerfile有自己书写格式和支持的命令,Docker程序解决这些命令间的依赖关系,类似于Makefile。Docker程序将读取Dockerfile,根据指令生成定制的image。相比image这种黑盒子,Dockerfile这种显而易见的脚本更容易被使用者接受,它明确的表明image是怎么产生的。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成image即可,省去了敲命令的麻烦。

Dockerfile结构
dockerfile由4部分信息组成:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令

# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..

# Base image to use, this must be set as the first line
FROM ubuntu

# Maintainer: docker_user <docker_user at email.com> (@docker_user)
MAINTAINER docker_user docker_user@email.com

# Commands to update the image
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf

# Commands when creating a new container
CMD /usr/sbin/nginx

其中#表注释,可以标注一些说明性的文字。

在 Dockerfile 中用到的命令有

✸FROM
FROM 指定镜像名称,格式为FROM <image> 或FROM <image>:<tag>,例如FROM ubuntu 或 FROM ubuntu:12.04。FROM 一定是首个非注释指令 Dockerfile.FROM 可以在一个 Dockerfile 中出现多次,以便于创建混合的images。如果没有指定 tag ,latest 将会被指定为要使用的基础镜像版本。

✸MAINTAINER
MAINTAINER 镜像作者 ,格式为 MAINTAINER <name>

✸RUN
RUN 格式为 RUN <command>或 RUN ["executable", "param1", "param2"]。前者将在 shell 终端中运行命令,即 /bin/sh -c;后者则使用 exec执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"]。
每条 RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \来换行。
RUN命令将在当前image中执行任意合法命令并提交执行结果。命令执行提交后,就会自动执行Dockerfile中的下一个指令。
层级 RUN 指令和生成提交是符合Docker核心理念的做法。它允许像版本控制那样,在任意一个点,对image 镜像进行定制化构建。
RUN 指令缓存不会在下个命令执行时自动失效。比如 RUN apt-get dist-upgrade -y 的缓存就可能被用于下一个指令. --no-cache 标志可以被用于强制取消缓存使用。

✸ENV
ENV 格式为 ENV <key> <value>。ENV设置的环境变量,可以使用 docker inspect命令来查看。同时还可以使用docker run --env <key>=<value>来修改环境变量。
例如:

ENV PG_MAJOR 9.3

ENV PG_VERSION 9.3.4

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

✸USER
USER 格式为 USER daemon。指定运行容器时的用户名或 UID,后续的RUN也会使用指定用户。
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要临时获取管理员权限可以使用 gosu,而不推荐 sudo。

✸WORKDIR
WORKDIR 格式为 WORKDIR /path/to/workdir。为后续的 RUN、CMD、ENTRYPOINT指令配置工作目录。可以使用多个 WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

则最终路径为 /a/b/c。

✸COPY
COPY 格式为 COPY <src> <dest>。
复制本地主机的 <src>(为 Dockerfile 所在目录的相对路径)到容器中的 <dest>。当使用本地目录为源目录时,推荐使用 COPY。
COPY和ADD的不同就是:ADD多了自动解压和支持URL路径的功能。

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

✸ADD
ADD 将文件从路径 <src> 复制添加到容器内部路径 <dest>。

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

✸VOLUME
VOLUME 格式为 VOLUME ["/data"]。创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。不过此属性在Dockerfile中指定并没有什么意义,因为没有办法指定本地主机的目录。如果需要指定挂载点可以在执行docker run命令时指定:

docker run -it -v /home/fengzheng/ftp/:/data 859666d51c6d /bin/bash

✸EXPOSE
EXPOSE 格式为 EXPOSE <port> [<port>...]。
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。

✸CMD
Dockerfile.中只能有一个CMD指令。 如果你指定了多个,那么最后个CMD指令是生效的。
CMD指令的主要作用是提供默认的执行容器。这些默认值可以包括可执行文件,也可以省略可执行文件。
当你使用shell或exec格式时, CMD会自动执行这个命令。
CMD支持三种格式:

CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式;
CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;

✸ONBUILD
ONBUILD 的作用就是让指令延迟執行,延迟到下一个使用 FROM 的 Dockerfile 在建立 image 时执行,只限延迟一次。格式为 ONBUILD [INSTRUCTION]。
ONBUILD 的使用情景是在建立镜像时取得最新的源码 (搭配 RUN) 与限定系统框架。
例如,Dockerfile 使用如下的内容创建了镜像 image-A。

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

如果基于 image-A 创建新的镜像时,新的Dockerfile中使用 FROM image-A 指定基础镜像时,会自动执行ONBUILD 指令内容,等价于在后面添加了两条指令。

FROM image-A
#Automatically run the following

ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src

使用 ONBUILD 指令的镜像,推荐在标签中注明,例如 ruby:1.9-onbuild。

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

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

✸ENTRYPOINT
ENTRYPOINT 两种格式:

ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2(shell中执行)。

配置容器启动后执行的命令,并且不可被 docker run提供的参数覆盖。
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。

✠注意

◆CMD 和 ENTRYPOINT 都能用来指定开始运行的程序,而且这两个命令都有两种不用的语法:

CMD ls -l
or
ENTRYPOINT ["ls","-l"]

对于第一种语法,docker 会自动加入“/bin/sh –c”到命令中,这样就有可能导致意想不到的行为。为了避免这种行为,我们推荐所有的 CMD 和 ENTRYPOINT 都应该使用第二种语法。
如果两个同时使用,请确定确定他们的含义没有错误。一般来说需要两个同时使用的情况只有 ENTRYPOINT 指定需要运行的 binary,CMD 给出运行的默认参数。

◆尽量合并命令
Dockerfile 中的每一个命令都会创建一个新的 layer,而一个容器能够拥有的最多 layer 数是有限制的。所以尽量将逻辑上连贯的命令合并可以减少 layer的层数,这也可以加快编译速度,合并命令的方法可以包括将多个可以合并的命令(EXPOSE, ENV,VOLUME,COPY)合并。比如:

EXOISE 80
EXOISE 8080
CMD cd /tmp
CMD ls

==>

EXOISE 80 8080
CMD cd /tmp && ls

◆ADD命令和 COPY 命令在很大层度上功能是一样的。但是 COPY 语义更加直接,所以我们推荐尽量使用 COPY 命令。唯一例外的是 ADD 命令自带解压功能,如果需要拷贝并解压一个文件到镜像中,那么我们可以使用 ADD 命令。除此之外,我们都推荐使用 COPY 命令。

ADD 1.1.1.100:1234/jdk-8u74-linux-x64.tar.gz /usr/local/

◆USER的使用
Docker 默认所有的应用都会跑在容器的 root user 底下,但是这样会造成一些潜在的安全隐患。在 production 环境跑的 Container 最好是通过USER命令跑在非特权用户底下。

✿以上信息copy自互联网✿

下面进行一个简单实战

利用Dockerfile创建镜像

环境准备:

mkdir /opt/docker-file/nginx/
cd /opt/docker-file/nginx/
wget http://app-zlf.oss-cn-hangzhou.aliyuncs.com/pcre-8.39.tar.gz
wget http://app-zlf.oss-cn-hangzhou.aliyuncs.com/nginx-1.10.1.tar.gz
vim Dockerfile

Dockerfile内容:

[root@test1 nginx]# cat Dockerfile
#This is My first Dockerfile
#Version 1.0
#Author: zlfzy
#Base images
FROM centos
#MAINTAINER
MAINTAINER zlfzy
#ADD
ADD pcre-8.39.tar.gz /usr/local/src
ADD nginx-1.10.1.tar.gz /usr/local/src
#RUN
RUN yum install -y wget gcc gcc-c++ make openssl-devel
RUN useradd www -M -s /sbin/nologin
#WORKDIR
WORKDIR /usr/local/src/nginx-1.10.1
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_stub_status_module --with-pcre=/usr/local/src/pcre-8.39 && make && make install
RUN echo "daemon off;" >>/usr/local/nginx/conf/nginx.conf
ENV PATH /usr/local/nginx/sbin:$PATH
EXPOSE 80
CMD ["nginx"]

启动镜像:

docker build -t nginx-file:v1 .    #其中.表示在当前目录下搜索Dockerfile文件,-t参数指定镜像名称和tag。
docker run -d -p 94:80 nginx-file:v1 /usr/local/nginx/sbin/nginx
docker ps -l

浏览器验证:
TIM图片20170519144739.png

添加新评论