本文介绍如何利用dockerfile来创建镜像。下面介绍具体的操作过程:

一、创建构建环境

操作示例如下:

xxx@ubuntu:~$ pwd
/home/xxx
xxx@ubuntu:~$ mkdir myweb
xxx@ubuntu:~$ cd myweb
xxx@ubuntu:~/myweb$ touch Dockerfile

上面命令在当前用户(xxx)的主目录下创建了一个myweb目录,并在该目录下建立了一个空的文件名为Dockerfile文件。
这个目录就是我们的构建环境(或上下文)。

二、编写Dockerfile文件内容

Dockerfile文件中,是一系列的指令组成。每条指令,包括指令名(必须大写)和指令所需的参数。看一个例子:

# version:0.0.
FROM ubuntu
MAINTAINER XXX "xxx@test.com"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'hello, i am a web image' > /usr/share/nginx/html/index.html
EXPOSE

文件的第一行是一条注释,在dockfile文件中,以#开头的表示注释。
当执行dockerfile文件时(如何执行,后面会介绍),其流程如下:

1、从基础镜像运行一个容器(第一条FROM指令的参数用于指定一个已经存在的基础镜像,每个dockerfile文件的第一条指令都是FROM)

2、在上面创建的容器中,执行一条指令,对容器做出修改(一般指令总会对容器进行一些改变,否则该指令就不需要了)

3、执行类似docker commit命令,提交一个新的镜像层(该层的内容就是上面指令造成的变化内容)

4、基于刚提交的镜像运行一个新的容器。

5、重复2~4步骤,逐个执行dockerfile中的所有指令。

看到这里大家可以有个疑问,为何每条指令都要创建镜像和容器呢,而不是只只在开始创建一次容器,然后基于该容器执行所有指令,完成所有修改后,再提交生成一个镜像呢?

这正是docker镜像分层特点的优势。可以想象一下,采用这种放的好处是,即使因为某种原因导致某条指令失败,但我们还是可以得到一个可用的镜像,然后我们就可以通过该镜像运行一个容器,在该容器中执行失败的指令,从而方便的进行调试,找到失败原因。

下面我们来介绍上面dokcerfile文件中每一行的意义:

1、第一行上面已经介绍,以#开头,是注释。

2、第二行FROM指令,用于指定基础镜像。是所有dockerfile的第一条命令。因为所有新的镜像都会基于该基础镜像基础上变化来的。

3、第三行 MAINTAINER指令,是标识镜像的作者和联系方式(这里是电子邮件),以方便镜像使用者和作者联系。

4、第四~六行RUN指令,用于在容器中执行参数指定的命令。上面的例子第4行是更新已经安装的APT仓库,第5行是下载安装nginx包,第6行是生成一个html文件,文件中只包含简单的一句话。

5、最后一行EXPOSE指令,告诉docker守护进程,容器的应用将使用指定的端口号(EXPOSE指令的参数,这个例子是80)。

三、构建镜像

通过docker build命令运行dockerfile文件,最后生成需要的镜像。命令如:

docker build -t="jene/myweb" .

参数-t指定生成镜像的所属用户名和仓库名,也可以有tag标识(这个例子没写,默认为latest)。 命令的最后点 不是结束符,而是表示Dockerfile文件在当前路径下。也可以指定一个git仓库的地址(只要该地址下有Dockerfile),则会利用git仓库中的dockerfile文件来构建镜像。

执行的过程会详细 输出每条指令执行的详细信息。

构建成功后,我们就可以用 docker images命令查看新构建的镜像,也可以用docker history命令查看新构建镜像的构建历史。

四、创建容器和启动容器中的web服务

docker run -d -p 80 --name myweb 1311399350/myweb nginx -g "daemon off;"

上面命令创建和运行了容器,并将nginx服务启动了。

上面命令除 -p参数外,其它参数前面文章都介绍过了。-d表示是 容器。 --name指定容器名,这里是myweb。 后面的是镜像名。以及要执行的命令(这里是启动nginx服务)。 -p参数我们下面详细介绍。

下面我们来通过curl工具测试这个web服务是否可用。

1、先进入容器内访问

docker exec -i -t myweb /bin/bash    //进入容器的交互式shell

curl localhost:80   //可能容器中没有curl工具

输出如下内容
hello, i am a web image

2、在主机上访问容器内的服务

首先查看容器内的80端口与主机上的端口的映射关系

运行 docker port myweb 80 显示信息如下

0.0.0.0:32768

这里可以看出,映射的端口是32768.

我们在主机执行:

curl localhost:32768

输出
hello, i am a web image

3、在主机以外的局域网内的其它机器访问

先用ifconfig查看dokcer主机的ip地址,如 192.168.142.138

在其它机器上通过  http://192.168.142.138:32768/ 一样可以访问到 index.html网页。

五、容器的端口配置

方法一:自动映射

docker run -d -p 80 --name myweb 1311399350/myweb nginx -g "daemon off;"

上面的 -p 80 ,将在docker主机上随机打开一个端口(可利用docker port命令查看,或者docker ps也能看到,这里是32768)映射到容器中的80端口上。

方法二:指定映射

除了自动映射外,还可以指定映射关系,如:

docker run -d -p 80:80 --name myweb 1311399350/myweb nginx -g "daemon off;"

docker port myweb 80
0.0.0.0:80

可以看出,主机上的80端口映射到容器的80端口。

这样指定的方式有好有怀,坏处是,第一无法运行多个同样的容器,第二容易与主机上的应用冲突。好处是端口是已知的。需要小心使用。

方法三:公开dockerfile中EXPOSE指令指定的端口

docker run -d -P --name myweb 1311399350/myweb nginx -g "daemon off;"

利用大些的-P参数,将dockerfile中EXPOSE指令指定的端口(容器内端口)对本地宿主主机公开,并随机绑定到本地宿主主机的端口上。

docker port myweb 80
0.0.0.0:32771

注意: 在docker run命令中通过 -p标记暴露的容器端口,并不一定需要在dockerfile文件中用EXPOSE指令配置。

在dockerfile文件中用EXPOSE指令配置端口,其好处是在docker run命令中可以用-P标记来全部暴露,省去了在docker run命令中用-p来逐个指定。

docker学习笔记6:利用dockerfile创建镜像介绍(生成简单web服务器镜像)的更多相关文章

  1. docker学习笔记18:Dockerfile 指令 VOLUME 介绍

    在介绍VOLUME指令之前,我们来看下如下场景需求: 1)容器是基于镜像创建的,最后的容器文件系统包括镜像的只读层+可写层,容器中的进程操作的数据持久化都是保存在容器的可写层上.一旦容器删除后,这些数 ...

  2. Docker学习笔记之通过 Dockerfile 创建镜像

    0x00 概述 由于 Docker 镜像的结构优势,使它的占用空间远小于普通的虚拟机镜像,而这就大幅减少了 Docker 镜像在网络或者其他介质中转移所花费的时间,进而提高了我们进行迁移部署的效率.不 ...

  3. Docker学习笔记_使用Dockerfile创建flask的一个镜像

    一.实验环境 1.宿主机OS:Win10 64位 2 .虚拟机OS:Ubuntu18.04 64位    虚拟机名称:Ubuntu18VM1   虚拟机IP:192.168.8.25 3.账号:doc ...

  4. docker学习笔记17:Dockerfile 指令 ONBUILD介绍

    ONBUILD指令可以为镜像添加触发器.其参数是任意一个Dockerfile 指令. 当我们在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A ...

  5. docker学习笔记11:Dockerfile 指令 CMD介绍

    我们知道,通过docker run 创建并启动一个容器时,命令的最后可以指定容器启动后在容器内立即要执行的指令,如: docker run -i -t ubunu /bin/bash   //表示容器 ...

  6. docker学习笔记14:Dockerfile 指令 ENV介绍

    ENV指令用来在镜像构建过程中设置环境变量.我们来看一个Dockerfile的例子: #test FROM ubuntu MAINTAINER hello ENV MYDIR /mydir RUN m ...

  7. docker学习笔记13:Dockerfile 指令 WORKDIR介绍

    Dockerfile中的WORKDIR指令用于指定容器的一个目录, 容器启动时执行的命令会在该目录下执行. 相当于设置容器的工作目录了.我们来看一个dockerfile文件 #test FROM ub ...

  8. docker学习笔记12:Dockerfile 指令 ENTRYPOINT介绍

    本文介绍Dockerfile的 ENTRYPOINT指令的含义. 先回顾下CMD指令的含义,CMD指令可以指定容器启动时要执行的命令,但它可以被docker run命令的参数覆盖掉. ENTRYPOI ...

  9. docker学习笔记15:Dockerfile 指令 USER介绍

    USER指令用于指定容器执行程序的用户身份,默认是 root用户. 在docker run 中可以通过 -u 选项来覆盖USER指令的设置. 举例:docker run -i -t -u mysql ...

随机推荐

  1. onpagehide、onunload 和 onpageshow、onload事件疑惑

    今天在最新版本chrome浏览器中测试在什么情况下会触发onpagehide.onunload事件(点击一个链接,刷新页面,提交表单,关闭浏览器等).测试代码粘贴如下: <!DOCTYPE ht ...

  2. swiper,animate使用方法

    1.先链接css和js文件 <link rel="stylesheet" type="text/css" href="css/swiper-3. ...

  3. React Native-目前最火的前端技术?

    做为一名产品经理,你是否遇到过这样的窘境,“帮我把字体调成 16号呗,颜色变成 #FFFF00FF,老大说这里最好改一下”,作为一名 app 的开发只能无奈但心里窃喜的告诉你,“只能等下个版本了,必须 ...

  4. mobilize扁平化的fullPage.js类工具使用心得

    可以生成一个fullPage效果的主页,但是列表页面和内容页面呢? 主页中的block,可以选择多种组建生成.甚至连form都有: 应该改造其源代码,动态化和cms系统化,添加二三级页面模板: == ...

  5. Notepad++中Windows,Unix,Mac三种格式

    Notepad++中Windows,Unix,Mac三种格式之间的转换 http://www.crifan.com/files/doc/docbook/rec_soft_npp/release/htm ...

  6. 数据层使用DBHelper.dll来减少工作量

    目前在需求确定了以后进行开发的步骤一般是这样的:建立数据表,建立model,构建数据操作层,最后在页面中进行调用.关于数据操作层,因为大量的操作都集中在增加.更新.删除等简易操作,而我之前的写法是每次 ...

  7. Python:爬取乌云厂商列表,使用BeautifulSoup解析

    在SSS论坛看到有人写的Python爬取乌云厂商,想练一下手,就照着重新写了一遍 原帖:http://bbs.sssie.com/thread-965-1-1.html #coding:utf- im ...

  8. Spark Streaming连接TCP Socket

    1.Spark Streaming是什么 Spark Streaming是在Spark上建立的可扩展的高吞吐量实时处理流数据的框架,数据可以是来自多种不同的源,例如kafka,Flume,Twitte ...

  9. 如何去掉Protel99se汉化菜单

    说明: 安装Protel99se汉化包后,卸载后重新安装也无法去掉汉化菜单.本文介绍解决办法. 问题: 网上一些Protel99se的安装包内,在介绍Protel安装时,采用3大步的方法.第一步安装P ...

  10. Qt中将QTableView中的数据导出为Excel文件

    如果你在做一个报表类的程序,可能将内容导出为Excel文件是一项必须的功能.之前使用MFC的时候我就写过一个类,用于将grid中的数据导出为Excel文件.在使用了QtSql模块后,我很容易的将这个类 ...