在上一篇文章中,我们讲述了 Dockerfile
的组成以及指令的编写过程,在本篇文章中详细讲解如何构建 Dockerfile
。
Dockerfile常用的指令
那么在讲如何构建 Dockerfile
之前,我们回顾一下上一篇的编写过程:
-
1、从
DockerHub
上pull
下指定的基础镜像 -
2、显示维护者的信息
-
3、
copy
当前目录到容器中的指定目录下 复制本地主机的<src>
(Dockerfile
所在目录的相对路径)到容器里<dest>
-
4、指定工作路径
-
5、安装依赖包
-
6、暴露端口
-
7、启动容器
我们已经差不多知道了 Dockerfile
的组成以及指令的编写过程,我们再来理解一下这些常用命令就会得心应手了。
由于 Dockerfile
中所有的命令都是以下格式: INSTRUCTION argument
,指令 (INSTRUCTION)
不分大小写,但是推荐大写,和sql语句是不是很相似呢?下面我们正式来讲解一下这些指令集吧。
FROM
FROM
是用于指定基础的 images
,一般格式为 FROM<image>
or FORM<image>:<tag>
,所有的 Dockerfile
都用该以 FROM
开头, FROM
命令指明 Dockerfile
所创建的镜像文件以什么镜像为基础, FROM
以后的所有指令都会在 FROM
的基础上进行创建镜像。可以在同一个 Dockerfile
中多次使用 FROM
命令用于创建多个镜像。比如我们要指定 python2.7
的基础镜像,我们可以像如下写法一样:
-
FROM python:2.7
MAINTAINER
MAINTAINER 是用于指定镜像创建者和联系方式,一般格式为 MAINTAINER<name>
。这里我设置成我的 ID
和邮箱:
-
MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>
COPY
COPY
是用于复制本地主机的 <src>
(为 Dockerfile 所在目录的相对路径)到容器中的 <dest>
。
当使用本地目录为源目录时,推荐使用 COPY
。一般格式为 COPY<src><dest>
。例如我们要拷贝当前目录到容器中的 /app
目录下,我们可以这样操作:
-
COPY . /app
WORKDIR
WORKDIR
用于配合 RUN
, CMD
, ENTRYPOINT
命令设置当前工作路径。可以设置多次,如果是相对路径,则相对前一个 WORKDIR
命令。默认路径为 /
。一般格式为 WORKDIR/path/to/work/dir
。例如我们设置 /app
路径,我们可以进行如下操作:
-
WORKDIR /app
RUN
RUN
用于容器内部执行命令。每个 RUN
命令相当于在原有的镜像基础上添加了一个改动层,原有的镜像不会有变化。一般格式为 RUN<command>
。例如我们要安装 python
依赖包,我们做法如下:
RUN pip install -r requirements.txt
EXPOSE
EXPOSE
命令用来指定对外开放的端口。一般格式为 EXPOSE<port>[<port>...]
例如上面那个例子,开放5000端口:
-
EXPOSE 5000
ENTRYPOINT
ENTRYPOINT
可以让你的容器表现得像一个可执行程序一样。一个 Dockerfile
中只能有一个 ENTRYPOINT
,如果有多个,则最后一个生效。
ENTRYPOINT
命令也有两种格式:
ENTRYPOINT["executable","param1","param2"] :推荐使用的 exec形式 ENTRYPOINT command param1 param2 : shell 形式
例如下面这个,我们要将 python
镜像变成可执行的程序,我们可以这样去做:
-
ENTRYPOINT ["python"]
CMD
CMD
命令用于启动容器时默认执行的命令, CMD
命令可以包含可执行文件,也可以不包含可执行文件。不包含可执行文件的情况下就要用 ENTRYPOINT
指定一个,然后 CMD
命令的参数就会作为 ENTRYPOINT
的参数。
CMD
命令有三种格式:
CMD["executable","param1","param2"]:推荐使用的 exec 形式。 CMD["param1","param2"]:无可执行程序形式 CMD command param1 param2:shell 形式。
一个 Dockerfile
中只能有一个 CMD
,如果有多个,则最后一个生效。而 CMD
的 shell
形式默认调用 /bin/sh-c
执行命令。
CMD
命令会被 Docker
命令行传入的参数覆盖: docker run busybox/bin/echoHello
Docker
会把 CMD
里的命令覆盖。
例如我们要启动 /app
,我们可以用如下命令实现:
-
CMD ["app.py"]
当然还有一些其他的命令,我们在用到的时候再去一一讲解一下。
构建Dockerfile
我们大体已经把Dockerfile的写法讲述完毕,我们可以自己动手写一个例子:
~~~shell mkdir staticweb cd staticweb touch Dockerfile 然后 vi Dockerfile 开始编辑该文件 输入 i 开始编辑
以下是我们构建的Dockerfile内容
FROM nginx MAINTAINER Angel_Kitty <angelkitty6698@gmail.com> RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html ```````
编辑完后 按 esc 退出编辑 然后 :wq 写入 退出 ~~~
我们在 Dockerfile
文件所在目录执行:
-
docker build -t angelkitty/nginx_web:v1 .
我们解释一下, -t
是为新镜像设置仓库和名称,其中 angelkitty
为仓库名, nginx_web
为镜像名, :v1
为标签(不添加为默认 latest
)
我们构建完成之后,使用 docker images
命令查看所有镜像,如果存在 REPOSITORY
为 nginx
和 TAG
是 v1
的信息,就表示构建成功。
接下来使用 docker run
命令来启动容器
docker run --name nginx_web -d -p 8080:80 angelkitty/nginx_web:v1
这条命令会用 nginx 镜像启动一个容器,命名为 nginx_web
,并且映射了 8080 端口,这样我们可以用浏览器去访问这个 nginx
服务器: http://localhost:8080/
或者 http://本机的IP地址:8080/,页面返回信息:
这样一个简单使用 Dockerfile
构建镜像,运行容器的示例就完成了!
总结
到此为止,Docker的基础部分已经说的差不多了,在后续的文章中,我会带大家了解一些Docker底层实现的原理以及Linux内核部分。由于Docker是用Golang语言开发的,这时候我们可能需要Golang语言的基础,不过不必担心,只要你有C语言的基础就行,我们在后续的文章中讲解一点Golang语言相关的基础知识。