Docker Dockerfile的教程和构建图像的示例
目前的文章将在Dockerfile中行走Docker Ecosystem中最使用的概念之一。
我们将探索DockerFile的构建块,以自动构建Docker图像的应用程序和服务。
Dockerfile基本上是一个文本文件,包含一组指令或者命令瞄准Docker图像。
因此,调用Docker Build命令Docker读取Dockerfile的指令并捆绑Docker镜像。
我们将学到什么
- dockerfile指令
- 构建Docker图像的例子
文章的结构安排如下
- dockerfile使用
- Dockerfile结构和常用说明
- dockerfile例子
- 结论
dockerfile使用
主要是,构建Docker图像的命令如上所述Docker构建${上下文}; ${context}是我们的图像的上下文,它可以是主机文件系统中的文件夹的路径或者Git存储库的URL;粗略地介绍${上下文}是在构建阶段期间dockerfile所需的所有文件。
构建由Docker守护程序运行而不是Docker CLI。
所有${context}递归地向Docker守护程序发送,因此,强烈建议使用"/"作为图像上下文的路径,因为将发送到"/"的所有内容。
dockerfile必须位于${context}的根目录中。
Docker允许使用。
Dockerignore文件指定必须从构建中排除的所有文件和文件夹,因此,它们不会被发送到Docker守护程序,并通过这样做发送,因此我们将增加建筑物性能。
让我们创建一个简单的dockerfile,只包含一个指令,我稍后会解释:
>> docker-dockerfile cat Dockerfile FROM node:latest
从此DockerFile构建Docker的最简单方法是运行Docker构建并将当前目录作为${上下文}:
>> docker-dockerfile docker build . Sending build context to Docker daemon 2.048 kB Step 1 : FROM node:latest ---> 36dc1bb7a52b Successfully built 36dc1bb7a52b
可以通过添加-F参数来指定Dockerfile的路径:
>> Code docker build -f docker-dockerfile/Dockerfile docker-dockerfile/
Docker Image Building最重要的特征之一是能够标记我们的图像,以便我们可以通过标签(主要是名称)找到它们。
因此,要标记图像,我们必须添加Argument -T和标记名称;我们还可以通过添加-t ${tag_name}:${version}分配图像的版本
>> docker-dockerfile docker build -t theitroad/nodejs . >> docker-dockerfile docker build -t theitroad/nodejs:0.0.1 .
我们可以检查内置图像是否:
>> docker-dockerfile docker images theitroad/nodejs REPOSITORY TAG IMAGE ID CREATED SIZE theitroad/nodejs 0.0.1 36dc1bb7a52b 2 weeks ago 655.5 MB theitroad/nodejs latest 36dc1bb7a52b 2 weeks ago 655.5 MB
dockerfile结构
dockerfile的格式/结构非常简单,这基本上如下:
# Comment goes here INSTRUCTION argument1 argument2 argument3 …
指令是非区分大小写的,但由于会议开发人员使用以大写格式编写指令。
dockerfile中指令的顺序很重要,这是相同的次数遵循图像构建时间。
.dockerignore文件
以下是一个例子。
Dockeringore文件,说明所有何种形式允许从Docker Image构建中排除文件或者文件夹:
>> docker-dockerfile cat .dockerignore # this is a comment */temp* */*/temp* temp? node_modules/ .git/
- */temp *:排除名称以temp开头的所有文件或者目录,并且是根的子目录,例如of the root,例如of the root,fearte_folder/temp.txt/parent_folder/tempo /等。
- //temp *:与第一个相同,但root是两个级别
- temp?:涉及临时像速度等一个字符的文件或者目录。
- node_modules /:从build中排除文件夹node_modules /在当前文件夹中。
- .git /:排除隐藏文件夹.git /在build的当前文件夹中。
从以来开始的所有行都被视为注释,因此它们在构建时被忽略。
Dockerfile结构和常用说明
1)FROM
从指令设置后续指令的基础图像设置。
基本上,有效的Dockerfile必须在没有考虑注释的情况下从指令中获得的第一行。
Docker守护程序将首先检查图像是否存在于主机中,否则将从Docker Hub中拉出来。
该指令有三种形式:
FROM <image> FROM <image:tag> FROM <image><@digest>
从:
- 必须是第一个非注释行
- 可以在同一个dockerfile中看起来多次
- <image> @ <digest>和<tag>是可选的,如果指定的Docker将拉动确切的图像,否则它将拉动最新图像。
在我们的第一个例子中(见上文)我们使用nodejs镜像使用: FROM node:latest
2)MAINTAINER
此指令允许我们指定内置镜像的作者;例如
MAINTAINER <name>
# Example 2: FROM node:latest MAINTAINER theitroad
3)RUN
该指令旨在执行命令。
该命令将在图像顶部的新图层中执行并提交结果,该结果将用作下一个指令的图像等。
运行有两个表单,shell表单和exec:
RUN <command> : shell格式,该命令在shell中运行,默认/bin/sh -c for linux或者cmd/s/c for windows。 RUN [“executable", “argument1", “argument2", “argument3" …]
将Run命令添加到我们的dockerfile示例中:
# Example 1 # --------- FROM node:latest # Example 2 # --------- MAINTAINER theitroad # Example 3 # --------- RUN /bin/sh -c 'echo "*** hello Dockerfile!! ***"' RUN ["npm", "--version"]
让我们构建图像以查看此示例在操作中,请注意该命令的"echo"*** hello dockerfile !! ***"和npm -version已被执行。
>> docker-dockerfile docker build -t theitroad/nodejs:0.0.3 . … Step 3 : RUN /bin/sh -c 'echo "*** hello Dockerfile!! ***"' ---> Running in 6ebdd85f7687 *** hello Dockerfile!! *** … Step 4 : RUN npm --version ---> Running in bc9dbc7cf8c1 3.10.10 …
4)标签
此指令将Metadata添加到图像中作为键值对。
格式如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
- 我们可以使用多行标签:
LABEL "com.example.image "="Node Js image LABEL example" LABEL version="0.0.4" LABEL description=" label-values \ can span multiple lines."
- 我们可以使用具有多个键值对的一行标签:
LABEL "com.example.image"="Node Js image LABEL example" version="0.0.4" description=" label-values \ can span multiple lines."
让我们构建图像:
>> docker-dockerfile docker build -t theitroad/nodejs:0.0.3 . --no-cache=true
检查镜像:
>> docker-dockerfile docker inspect theitroad/nodejs:0.0.3 … "Labels": { "com.example.image": "Node Js image LABEL example", "description": " label-values can span multiple lines.", "version": "0.0.4" } …
5)EXPOSE
EXPOSE <port> [<port>...]
此指令通知Docker Container在运行时在指定的网络端口上侦听。
它不会使主机可访问的容器的端口。
为此,必须使用-p标志来发布一系列端口或者-p标志,以发布所有公开的端口。
# Example 1 # --------- FROM node:latest # Example 2 … # Example 5 # --------- EXPOSE 3000
6)ENV.
按照与标签相同的格式,但要定义环境变量。
… # Example 6 # --------- ENV mysql_root_password test dsf ENV src_folder ./src/app
构建图像并检查它以检查env变量:
>> docker-dockerfile docker build -t theitroad/nodejs:0.0.3 . --no-cache=true >> docker-dockerfile docker inspect theitroad/nodejs:0.0.3 … "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "NPM_CONFIG_LOGLEVEL=info", "NODE_VERSION=7.2.1", "mysql_root_password=test dsf", "src_folder=./src/app" ] …
7)ADD
此指令从<src>复制新文件,目录或者远程文件URL,并将其添加到PATH <DEST>的图像的文件系统。
格式是:
ADD <src>... <dest> but if the paths containing whitespace we need to use ADD ["<src>",... "<dest>"]
... # Example 7 # --------- ADD . /src/app/
此示例将当前目录内容复制到图像中的/src/app /中。
- 如果<dest>不以尾随斜杠结束,则将被视为常规文件,并且<src>的内容将写在<dest>。
- 如果<dest>不存在,则它将与其路径中的所有缺少目录一起创建。
- 在<SRC>路径中允许基本通配符,Dist * Readm?.txt等。
如果<src>是存档(tar,gzip,bzip2或者xz)添加将自动解压缩<dest>
8)COPY
这条指令非常类似于添加和几乎做同样的事情。
复制与添加具有相同的表单,它将文件/目录复制到<src>进入<dest>。
实际上,与添加不同,副本不会除URL作为<SRC>,它不会解压缩归档<SRC>文件。
9)ENTRYPOINT
此命令允许我们指定启动命令,该命令将始终在容器启动时执行。
... # Example 8 # --------- ENTRYPOINT ["/bin/echo", "Hello theitroad"]
重建Docker图片:
>> docker-dockerfile docker build -t theitroad/nodejs:0.0.3 . --no-cache=true
从内置图像运行一个容器:
>> docker-dockerfile docker run -it --name nodejs-dockerfile theitroad/nodejs:0.0.3 Hello theitroad
请注意,只允许使用dockerfile的一个入口点。
10)cmd.
命令cmd几乎与命令ententpoint相似,也是dockerfile允许的一个命令。
入口点和CMD之间的主要区别在于,一旦在Docker运行中指定了命令,省略了CMD ...
... # Example 8 # --------- ENTRYPOINT ["/bin/echo", "Hello theitroad"]
# Example 9 # --------- CMD ["Yo World!!"]
重建图像:
>> docker-dockerfile docker build -t theitroad/nodejs:0.0.3 . --no-cache=true
创建一个Docker容器
>> docker-dockerfile docker run -it --name nodejs-dockerfile theitroad/nodejs:0.0.3 Hello theitroad Yo World!!
通过在Docker运行结束时添加命令来创建第二个容器,因此,CMD将省略:
>> docker-dockerfile docker run -it --name nodejs-dockerfile2 theitroad/nodejs:0.0.3 Horay Hello theitroad Horay
11)VOLUME
卷令创建具有指定名称的挂载点,并将其标记为从本机主机或者其他容器中持有外部安装卷。
# Example 10 # --------- VOLUME /var/log
12)USER
USER <daemon or UID>
用户指令设置在运行图像时使用用户名或者UID,并用于任何运行,CMD和EntryPoint指令。
# Example 11 # --------- USER deep
13)Workdir.
Workdir/path/to /文件夹
该指令为Dockerfile中的任何运行,CMD,EntryPoint,复制和添加说明设置了工作目录。
如果Workdir不存在,则将创建该文件夹以及父文件夹。
我们可以理解Workdir作为Linux的CD'命令,除了将创建文件夹,不存在。
dockerfile例子
请参阅每个DockerFile示例中的注释。
nodejs app dockerfile示例:
FROM node:argon # Create app directory RUN mkdir -p /usr/src/app WORKDIR /usr/src/app # Install app dependencies COPY package.json /usr/src/app/ RUN npm install # Bundle app source COPY . /usr/src/app EXPOSE 8080 CMD [ "npm", "start" ]
nginx dockerfile示例:
FROM debian:jessie MAINTAINER NGINX Docker Maintainers "[email protected]" ENV NGINX_VERSION 1.11.7-1~jessie RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 \ && echo "deb http://nginx.org/packages/mainline/debian/jessie nginx" >> /etc/apt/sources.list \ && apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y \ ca-certificates \ nginx=${NGINX_VERSION} \ nginx-module-xslt \ nginx-module-geoip \ nginx-module-image-filter \ nginx-module-perl \ nginx-module-njs \ gettext-base \ && rm -rf /var/lib/apt/lists/* # forward request and error logs to docker log collector RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log EXPOSE 80 443 CMD [ "nginx", "-g", "daemon off;" ]