一、什么是 Dockerfile?
Dockerfile 是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了Dockerfile之后,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成镜像即可,省去了敲命令的麻烦。
二、Dockerfile文件格式
Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令、容器启动执行指令。
一开始必须要指明所基于的基础镜像名称,接下来一般会说明维护者信息,后面则是镜像操作指令,例如 RUN 指令。每执行一条RUN 指令,镜像添加新的一层,并提交;最后是 CMD 指令,来指明运行容器时的操作命令。
# 1、第一行必须指定 基础镜像信息 # 定制的镜像都是基于 FROM 的镜像,这里的ubuntu 就是定制需要的基础镜像。 # 后续的操作都是基于 nginx。 # FROM <image>:<tag> FROM ubuntu # 2、维护者信息 MAINTAINER docker_user docker_user@email.com # 3、镜像操作指令 # RUN:用于执行后面跟着的命令行命令。 有以下俩种格式: # shell 格式:RUN <命令行命令> # exec 格式:RUN ["可执行文件", "参数1", "参数2"] # 例如:RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline 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 # 4、容器启动执行指令 CMD /usr/sbin/nginx 复制代码
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。
例如:
FROM centos RUN yum install wget RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" RUN tar -xvf redis.tar.gz 复制代码
以上执行会创建 3 层镜像。可简化为以下格式:
FROM centos RUN yum install wget \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \ && tar -xvf redis.tar.gz 复制代码
如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。
三、构建 Docker 镜像
docker build 命令会根据 Dockerfile 文件及上下文构建新 Docker 镜像。构建上下文是指 Dockerfile 所在的本地路径或一个URL(Git仓库地址)。构建上下文环境会被递归处理,所以构建所指定的路径还包括了子目录,而URL还包括了其中指定的子模块。
# 构建镜像,将当前目录做为构建上下文 docker build -t test/myapp:v1 . # Dockerfile 一般位于构建上下文的根目录下, 也可以通过-f指定该文件的位置 # 还可以通过-t参数指定构建成镜像的仓库、标签 docker build -f /path/to/Dockerfile -t nginx:v1 . 复制代码
你会看到 docker build
命令最后有一个 .
。
.
表示当前目录,其实这个是在编译时构建docker上下文路径。
什么是上下文路径?
上下文路径是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
四、制作一个简单的Dockerfile
1、准备一个nginx的基础镜像。
docker pull library/ngnix 复制代码
在镜像列表中会看到我们从远程仓库中获取的nginx镜像。
docker images | grep ngnix 复制代码
2、准备好了基础镜像,编写Dockerfile
以定制 nginx 镜像为例,在一个空白目录中,建立一个文本文件,并命名为 Dockerfile
mkdir mydocker cd mydocker touch Dockerfile 复制代码
构建一个 Dockerfile 内容如下:
FROM nginx RUN echo '<h1>hello, docker!</h1>' > /usr/share/nginx/html/index.html 复制代码
这个 Dockerfile 一共就两行涉及到了两条指令:FROM 和 RUN,FROM 表示获取指定基础镜像,RUN 执行命令,在执行的过程中重写了 nginx 的默认页面信息,将信息替换为:Hello, Docker!。
4、用Dockerfile 来构建镜像
在 Dockerfile 文件所在目录执行:
docker build -t nginx:v1 . 复制代码
构建完成之后,使用 docker images 命令查看所有镜像,如果存在 REPOSITORY 为 nginx 和 TAG 是 v1 的信息,就表示构建成功。
docker images | grep nginx:v1 docker images nginx:v1 复制代码
5、接下来使用 docker run 命令来启动容器
docker run --name docker_nginx_v1 -itd -p 80:80 nginx:v1 复制代码
这条命令会用 nginx 镜像启动一个容器,命名为docker_nginx_v1,并且映射了 80 端口,这样我们可以用浏览器去访问这个 nginx 服务器
6、访问这个 nginx 服务器
curl 127.0.0.1 复制代码
返回如下信息: <h1>hello, docker!</h1>
,则表示成功。
7、查看运行的容器docker_nginx_v1
docker ps | grep docker_nginx_v1 复制代码
8、查看容器日志
# docker logs -f -t 容器ID docker logs -f -t 0ad2db0945d7e717f5d02ad3d1a8b548ed50ba8570179638ff4b3df2fb127c7f 复制代码
9、进入容器内
docker exec -i -t docker_nginx_v1 /bin/bash 复制代码
10、根据容器ID删除容器
docker rm -f e3811b67f691 复制代码
11、根据镜像ID删除镜像
# docker rmi [Image ID] docker rmi 43757978f723 复制代码
至此,一个简单的Docker镜像就制作完成,并且能够通过镜像启动容器运行了。