Dockerfile实践


title: Dockerfile实践
date: 2018-09-27 15:58:51
tags: Dockerfile
categories: Docker
catalog: true


Dockerfile是用于构建Dcoker镜像的文件。在前面我们使用docker commit时也创建了一个新镜像,但使用Dockerfile构建新镜像是常用的方式。在编写好Dockerfile文件后,使用docker build命令即可构建一个新的镜像。Dockerfile文件的编写需要遵循一些规范。

Dockerfile的文件结构

Dockerfile的编写与脚本文件类似,注释使用#

一般Dockerfile文件分成四个部分:基础镜像信息、维护者信息、镜像操作命令、容器启动时执行的命令

基本格式如下,分别对应上面的四个部分:

FROM ... 		
MAINTAINER ...	
RUN ...			
CMD ...			

第一条指令必须是FROM,如果在同一个Dockerfile文件中创建多个镜像时,可以使用多个FROM(每个镜像一次)

Dockerfile常用语法

下面总结一些Dockerfile文件中常用的语法:

命令 用途
FROM base image(基础镜像)
RUN 执行命令
ADD 添加文件
ARG 设置构建参数
COPY 复制文件
CMD 执行命令
EXPOSE 暴露端口
WORKDIR 指定路径
MAINTAINER 维护者
ENV 设定环境变量
ENTRYPOINT 容器入口
USER 指定用户
VOLUME mount point 指定挂载点

Dockerfile实践

下面写一些小实例,通过编写Dockerfile来构建我们自己的镜像。

创建Dockerfile

在一个新目录下创建如下内容的Dockerfile:

# 基础镜像
FROM ubuntu	
# 维护者
MAINTAINER hjw					
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
# 执行更新命令
RUN apt-get update	
# 安装nginx
RUN apt-get install -y nginx
# 将index.html复制到指定目录
COPY index.html /var/www/html	
# 容器入口命令
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
# 暴露端口
EXPOSE 80						

上面文件中sed命令主要是为了加速。替换apt-get的源地址,使用国内的镜像

Dockerfile中写的命令作用可以看上面的注释。

ENTRYPOINT的作用主要是指定容器入口即启动时执行的命令,后面为一个数组形式,展开后则是一条命令行。执行这条命令行的主要作用是将nginx在前台执行而不是作为守护进程执行。

另外再创建index.html文件,内容自定。

最终文件夹中的内容如下:

[root@HJWDEV ubuntu-nginx]# ll
总用量 4
-rw-r--r--. 1 root root  0 9月  26 16:06 Dockerfile
-rw-r--r--. 1 root root 54 9月  26 10:53 index.html

构建镜像

使用docker build命令来构建新的镜像,build 时Docker会在指定的目录中读取Dockerfile文件,并将该目录下的所有内容发送给Docker 服务端,由服务端来构建镜像。也可以通过.dockerignore文件(每一行添加一条匹配模式)来让 Docker 忽略路径下的目录和文件。镜像构建命令如下:

[root@HJWDEV docker]# docker build -t ubuntu-nginx ubuntu-nginx/.

-t 指定image标签,即镜像名称

最后为构建目录的路径,如果是在ubuntu-nginx目录下执行构建命令直接使用.即可。执行后Docker会按Dockerfile中的命令去构建我们的镜像。

执行成功后可以查看镜像是否生成:

[root@HJWDEV docker]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu-nginx        latest              f6538f6564f6        15 minutes ago      186MB
hello-docker        latest              be221a20a4d7        3 hours ago        4.41MB

运行镜像

运行ubuntu-nginx镜像

[root@HJWDEV docker]# docker run -d -p 80:80 ubuntu-nginx

-p 表示端口映射,把nginx的 80 端口映射到宿主机的 80 端口

-d 表示允许该Container作为守护进程来执行

运行成功后访问 宿主机+80 端口,会显示index.html的内容。

镜像分层

因为镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

这种分层的方式可以让有相同内容的镜像共享某一层,可以减少存储压力。

Dockerfile实践_第1张图片

上图中下面的三层是只读层,Docker会把Dockerfile中的每一行都生成一层镜像,在image运行成一个容器时会生成一个容器层,即最上层,它是一个可读可写层。如果下面的层在容器运行中是需要被改动的,则该层会被复制到顶层,所以的改动都会在顶层进行。

你可能感兴趣的:(Docker)