参考:http://www.cnblogs.com/liuyansheng/p/6098470.html

一、dockerfile介绍

  是一种被Docker程序解释的脚本,Dockerfile由一条一条的指令组成,每条指令对应Linux下面的一条命令。Docker程序将这些Dockerfile指令翻译真正的Linux命令。Dockerfile有自己书写格式和支持的命令,Docker程序解决这些命令间的依赖关系,类似于Makefile。Docker程序将读取Dockerfile,根据指令生成定制的image。相比image这种黑盒子,Dockerfile这种显而易见的脚本更容易被使用者接受,它明确的表明image是怎么产生的。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成image即可,省去了敲命令的麻烦。

二、实验准备:

  1、创建 Dockerfile 文件

  首先,需要创建一个目录来存放 Dockerfile 文件,目录名称可以任意,在目录里创建Dockerfile文件:

[root@localhost ~]# mkdir wangmo
[root@localhost ~]# cd wangmo/
[root@localhost wangmo]# touch dockerfile

  使用vim/gedit编辑Dockerfile文件,根据我们的需求输入内容。

三、Dockerfile 基本框架

  Dockerfile一般包含下面几个部分:

    基础镜像:以哪个镜像作为基础进行制作,用法是FROM 基础镜像名称
    维护者信息:需要写下该Dockerfile编写人的姓名或邮箱,用法是MANITAINER 名字/邮箱
    镜像操作命令:对基础镜像要进行的改造命令,比如安装新的软件,进行哪些特殊配置等,常见的是RUN 命令
    容器启动命令:当基于该镜像的容器启动时需要执行哪些命令,常见的是CMD 命令或ENTRYPOINT
    在本节实验中,我们依次先把这四项信息填入文档。Dockerfile中的#标志后面为注释,可以不用写,另外实验楼的环境不支持中文输入,比较可惜。

  依次输入下面的基本框架内容:

# Version 0.1

# 基础镜像
FROM ubuntu:latest # 维护者信息
MAINTAINER shiyanlou@shiyanlou.com # 镜像操作命令
RUN apt-get -yqq update && apt-get install -yqq apache2 && apt-get clean # 容器启动命令
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

  上面的Dockerfile非常简单,创建了一个apache的镜像。包含了最基本的四项信息。

  其中FROM指定基础镜像,如果镜像名称中没有制定TAG,默认为latest。RUN命令默认使用/bin/sh Shell执行,默认为root权限。如果命令过长需要换行,需要在行末尾加\。CMD命令也是默认在/bin/sh中执行,并且默认只能有一条,如果是多条CMD命令则只有最后一条执行。用户也可以在docker run命令创建容器时指定新的CMD命令来覆盖Dockerfile里的CMD。

  这个Dockerfile已经可以使用docker build创建新镜像了,先构建一个版本shiyanloutest:0.1:

[root@localhost wangmo]# docker build -t wangmotest:0.1 .        #构建镜像
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:latest
latest: Pulling from ubuntu
576b12d1aa01: Pull complete
b5ce920a148c: Pull complete
274da7f89b05: Pull complete
0346cecb4e51: Pull complete
2e36b30057ab: Pull complete
f5bb94a8fac4: Pull complete
Digest: sha256:7c8894a0f32d3f1fadf086d18d12441ce0cd19295075af8dee34ce5e1f6c3ed1
Status: Downloaded newer image for ubuntu:latest
---> f5bb94a8fac4
Step 1 : MAINTAINER shiyanlou@shiyanlou.com
---> Running in 191d22125b22
---> c703996f3e87
Removing intermediate container 191d22125b22
Step 2 : RUN apt-get -yqq update && apt-get install -yqq apache2 && apt-get clean
---> Running in 18ff8781a66c
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package libatm1:amd64.
(Reading database ... 4764 files and directories currently installed.)
Preparing to unpack .../libatm1_1%3a2.5.1-1.5_amd64.deb ...
Unpacking libatm1:amd64 (1:2.5.1-1.5) ...
Selecting previously unselected package libmnl0:amd64.
...
...
...
Step 3 : CMD /usr/sbin/apache2ctl -D FOREGROUND
---> Running in 569852d0bdb1
---> 787a3ee0813e
Removing intermediate container 569852d0bdb1
Successfully built 787a3ee0813e [root@localhost wangmo]# docker images #查看镜像
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
wangmotest 0.1 787a3ee0813e 14 hours ago 254.3 MB
ubuntu latest f5bb94a8fac4 10 days ago 117.3 MB
centos latest 6cc2eba34ef6 4 weeks ago 192.5 MB
nginx latest cbfa3eb33c93 4 weeks ago 182.5 MB
registry latest 6e757ddb42c5 4 weeks ago 33.17 MB
<none> <none> 093e606554fe 10 months ago 301 MB
training/webapp latest 02a8815912ca 24 months ago 348.7 MB

使用该镜像创建容器web1,将容器中的端口80映射到本地80端口:

[root@localhost wangmo]# docker run -d -p 80:80 --name web1 wangmotest:0.1
44e51d913f3de3df28a4765685973900f5e953c0e6c98082a3e5a542da846947
[root@localhost wangmo]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44e51d913f3d wangmotest:0.1 "/usr/sbin/apache2ct 16 seconds ago Up 15 seconds 0.0.0.0:80->80/tcp web1

使用实验环境桌面上的浏览器打开localhost进行测试,查看是否apache已运行:

三、Dockerfile 编写常用命令

在上述基本的架构下,我们根据需求可以增加新的内容到Dockerfile中。后续的扩展操作都需要放置在Dockerfile的镜像操作部分。其中部分命令在本实验中并不会用到,但需要有所了解。

1、指定容器运行的用户

该用户将作为后续的RUN命令执行的用户。这个命令本实验不需要,但在一些需要指定用户来运行的应用部署时非常关键,比如提供hadoop服务的容器通常会使用hadoop用户来启动服务。

命令使用方式,例如使用shiyanlou用户来执行后续命令:

USER shiyanlou

2、指定后续命令的执行目录

由于我们需要运行的是一个静态网站,将启动后的工作目录切换到/var/www/html目录:

WORKDIR /var/www/html

3、对外连接端口号

由于内部服务会启动Web服务,我们需要把对应的80端口暴露出来,可以提供给容器间互联使用,可以使用EXPOSE命令。

在镜像操作部分增加下面一句:

EXPOSE 80

4、设置容器主机名

ENV命令能够对容器内的环境变量进行设置,我们使用该命令设置由该镜像创建的容器的主机名为shiyanloutest,向Dockerfile中增加下面一句:

ENV HOSTNAME shiyanloutest

5、向镜像中增加文件

向镜像中添加文件有两种命令:COPY 和ADD

COPY simplecloudsite /var/www/html

ADD 命令支持添加本地的tar压缩包到容器中指定目录,压缩包会被自动解压为目录,也可以自动下载URL并拷贝到镜像,例如:

ADD html.tar /var/www
ADD http://www.shiyanlou.com/html.tar /var/www

根据实验需求,我们把需要的一个网站放到镜像里,需要把一个tar包添加到apache的/var/www目录下,因此选择使用 ADD命令:

ADD html.tar /var/www

四、CMD 与 ENTRYPOINT

ENTRYPOINT 容器启动后执行的命令,让容器执行表现的像一个可执行程序一样,与CMD的区别是不可以被docker run覆盖,会把docker run后面的参数当作传递给ENTRYPOINT指令的参数。Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。docker run命令的-entrypoint参数可以把指定的参数继续传递给ENTRYPOINT

在本实验中两种方式都可以选择。

五、挂载数据卷

将apache访问的日志数据存储到宿主机可以访问的数据卷中:

VOLUME ["/var/log/apche2"]

六、设置容器内的环境变量

使用ENV设置一些apache启动的环境变量:

ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apche2
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apche2

七、使用 Supervisord

CMD如果只有一个命令,那如果我们需要运行多个服务怎么办呢?最好的办法是分别在不同的容器中运行,通过link进行连接,比如先前实验中用到的web,app,db容器。如果一定要在一个容器中运行多个服务可以考虑用Supervisord来进行进程管理,方式就是将多个启动命令放入到一个启动脚本中。

首先安装Supervisord,添加下面内容到Dockerfile:

RUN apt-get install -yqq supervisor
RUN mkdir -p /var/log/supervisor

拷贝配置文件到指定的目录:

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

其中supervisord.conf文件需要放在/home/shiyanlou/shiyanloutest下,文件内容如下:

[supervisord]
nodaemon=true [program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2ctl -D FOREGROUND"

如果有多个服务需要启动可以在文件后继续添加[program:xxx],比如如果有ssh服务,可以增加[program:ssh]

修改CMD命令,启动Supervisord

CMD ["/usr/bin/supervisord"]

八、从 Dockerfile 创建镜像

将上述内容完成后放入到/home/shiyanlou/shiyanloutest/Dockerfile文件中,最终得到的Dockerfile文件如下:

# Version 0.2

# 基础镜像
FROM ubuntu:latest # 维护者信息
MAINTAINER shiyanlou@shiyanlou.com # 镜像操作命令
RUN apt-get -yqq update && apt-get install -yqq apache2 && apt-get clean
RUN apt-get install -yqq supervisor
RUN mkdir -p /var/log/supervisor VOLUME ["/var/log/apche2"] ADD html.tar /var/www
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf WORKDIR /var/www/html ENV HOSTNAME shiyanloutest
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apche2
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apche2 EXPOSE 80 # 容器启动命令
CMD ["/usr/bin/supervisord"]

同时在/home/shiyanlou/shiyanloutest目录下,添加supervisord.conf文件:

[supervisord]
nodaemon=true [program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2ctl -D FOREGROUND"

并下载静态页面文件压缩包:

cd /home/shiyanlou/shiyanloutest
wget http://labfile.oss.aliyuncs.com/courses/498/html.tar

http://simplecloud.cn网站的页面tar包下载到/home/shiyanlou/shiyanloutest目录:

docker build 执行创建,-t参数指定镜像名称:

docker build -t shiyanloutest:0.2 /home/shiyanlou/shiyanloutest/

docker images 查看创建的新镜像已经出现在了镜像列表中:

docker inspect shiyanloutest:0.2 查看该镜像的详细信息:

 

由该镜像创建新的容器web2,并映射本地的80端口到容器的80端口:

docker run -d -p 80:80 --name web2 shiyanloutest:0.2

最后打开桌面上的firefox浏览器,输入本地地址访问127.0.0.1,看到我们克隆的琛石科技的网站:

编写dockerfile的更多相关文章

  1. 实战docker,编写Dockerfile定制tomcat8镜像,实现web应用在线部署

    最初在tomcat上部署web应用的方式,是通过maven的maven-compiler-plugin插件先打成war包,再将war包复制到tomcat的webapps目录下,后来用上了tomcat7 ...

  2. 编写 DockerFile

    编写 DockerFile 本节内容简介 在前面的实验中我们多次用到的 Dockerfile,在本实验里我们将通过完成一个实例来学习Dockerfile的编写. 本节中,我们需要依次完成下面几项任务: ...

  3. 编写Dockerfile自定义镜像

    要求 编写一个Dockerfile自定义centos镜像,要求在容器内部可以使用vim和ifconfig命令,并且登入落脚点为/usr/local 编写Dockerfile FROM centos M ...

  4. 编写 Dockerfile 生成自定义镜像

    一般情况下我们可以从公共渠道诸如 DockerHub 获取镜像上获取镜像,但是在实际生产过程中,往往需要定制化的镜像,例如修改一些配置文件,增加一些特殊的命令或软件等需求,这时就需要通过编写 Dock ...

  5. Docker实战(五)编写Dockerfile

    一.创建Dockerfile文件 首先,需要创建一个目录来存放 Dockerfile 文件,目录名称可以任意,在目录里创建Dockerfile文件: 二.Dockerfile 基本框架 Dockerf ...

  6. (转)编写 DockerFile

    这几天在研究怎样制作docker image. 其中使用dockerfile是一种可记录制作image的过程的并且是容易重复使用的一种方式.在园子里看到了一篇好文,于是分享到这里~~ 原文链接: ht ...

  7. 编写 Dockerfile 最佳实践

    官方仓库虽然有数十万计的免费镜像,但大多数无法直接满足公司业务需求,这就需要我们自己去定制镜像了. Docker通过Dockerfile自动构建镜像,Dockerfile是一个包含用于组建镜像的文本文 ...

  8. 学习编写Dockerfile

    前言 我们学习docker的话,其主要目的还是要用来改变我们部署应用程序的传统习惯,达到解放生产力,解放人力的目的.这篇则自己来熟悉一下dockerfile常用命令.并且尝试改变下生产环境手动部署应用 ...

  9. Docker实战-编写Dockerfile

    一.编译镜像 1. 编译镜像 Dockerfile类似于Makfile,用户使用docker build就可以编译镜像,使用该命令可以设置编译镜像时使用的CPU数量.内存大小.文件路径等 语法:doc ...

随机推荐

  1. node.js实现国标GB28181流媒体点播(即实时预览)服务解决方案

    背景 28181协议全称为GB/T28181<安全防范视频监控联网系统信息传输.交换.控制技术要求>,是由公安部科技信息化局提出,由全国安全防范报警系统标准化技术委员会(SAC/TC100 ...

  2. 九度OJ 1205:N阶楼梯上楼问题 (斐波那契数列)

    时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:3739 解决:1470 题目描述: N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式.(要求采用非递归) 输入: 输入包括一个整 ...

  3. iOS Base64加密

    1.Base64编码说明 Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式. 如果剩下的字符不足3个字节,则用0 ...

  4. EventLoop(netty源码死磕4)

    精进篇:netty源码  死磕4-EventLoop的鬼斧神工 目录 1. EventLoop的鬼斧神工 2. 初识 EventLoop 3. Reactor模式回顾 3.1. Reactor模式的组 ...

  5. The given 'driver' ] is unknown, Doctrine currently supports only the follo wing drivers: pdo_mysql, pdo_sqlite, pdo_pgsql, pdo_oci, oci8, ibm_db2, pdo

    [Doctrine\DBAL\DBALException]                                                  The given 'driver' ] ...

  6. ABAP面试经历【转http://blog.csdn.net/tsj19881202/article/details/8792742】

    本周三面试了一次HP的globe部门,整个过程自己感觉特别糟糕.总结了一下经验, 1.不能把自己平时做的东西,很好的用语言描述出来 2.技术点其实都会,但是不了解对方问题的意思,所以没能很好的回答对方 ...

  7. ALV行 列颜色设置

    ALV的颜色设置分为3种:行.列.单元格.   1.列颜色的设置   在 slis_t_fieldcat_alv-emphasize 中,写入需要的颜色代码.   Eg:   DATA: fc TYP ...

  8. 通过systemd配置Docker

    1. systemd Service相关目录 通常情况下,我们有3种方式可以配置etcd中的service.以docker为例,1)在目录/etc/systemd/system/docker.serv ...

  9. shell 查看系统有关信息

    磁盘: 查看磁盘空间或者挂载情况 df -ah 或者 df -h 内存: 查看内存使用情况 free -m total used free shared buffers cached Mem: -/+ ...

  10. 大话设计模式--观察者模式 Observer -- C++ 实现实例

    大话设计模式--1.观察者模式: 定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有的 观察者对象,使他们能够自动更新自己. 使用场合: 当一 ...