Docker实战(五)编写Dockerfile
一、创建Dockerfile文件
首先,需要创建一个目录来存放 Dockerfile 文件,目录名称可以任意,在目录里创建Dockerfile文件:

二、Dockerfile 基本框架
Dockerfile一般包含下面几个部分:
- 基础镜像:以哪个镜像作为基础进行制作,用法是
FROM 基础镜像名称 - 维护者信息:需要写下该Dockerfile编写人的姓名或邮箱,用法是
MANITAINER 名字/邮箱 - 镜像操作命令:对基础镜像要进行的改造命令,比如安装新的软件,进行哪些特殊配置等,常见的是
RUN 命令 - 容器启动命令:当基于该镜像的容器启动时需要执行哪些命令,常见的是
CMD 命令或ENTRYPOINT
在本节实验中,我们依次先把这四项信息填入文档。Dockerfile中的#标志后面为注释,可以不用写。
打开Dockerfile,依次输入下面的基本框架内容:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
# Version 0.1# 基础镜像FROM debian:latest# 维护者信息MAINTAINER wl1524520@gmail.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创建新镜像了,先构建一个版本dockertest:0.1:
|
1
2
|
# 在dockertest目录,即Dockerfile所在的目录执行docker build -t dockertest:0.1 . |
构建需要安装apache2,会花几分钟,最后查看新创建的镜像:

使用该镜像创建容器site1,将容器中的端口8888映射到本地80端口:
|
1
|
docker run -d -p 8888:80 --name site1 dockertest:0.1 |
使用浏览器打开localhost:8888进行测试,查看是否apache已运行:

三、Dockerfile 编写常用命令
在上述基本的架构下,我们根据需求可以增加新的内容到Dockerfile中。后续的扩展操作都需要放置在Dockerfile的镜像操作部分。
1)指定容器运行的用户
该用户将作为后续的RUN命令执行的用户。命令使用方式,例如使用nginx用户来执行后续命令:
|
1
|
USER nginx |
2)指定后续命令的执行目录
由于我们需要运行的是一个静态网站,将启动后的工作目录切换到/var/www/html目录:
|
1
|
WORKDIR /var/www/html |
3)对外连接端口号
由于内部服务会启动Web服务,我们需要把对应的80端口暴露出来,可以提供给容器间互联使用,可以使用EXPOSE命令。
在镜像操作部分增加下面一句:
|
1
|
EXPOSE 80 |
4)设置容器主机名
ENV命令能够对容器内的环境变量进行设置,我们使用该命令设置由该镜像创建的容器的主机名为dockertest,向Dockerfile中增加下面一句:
|
1
|
ENV HOSTNAME dockertest |
5)向镜像中增加文件
向镜像中添加文件有两种命令:COPY 和 ADD。
COPY命令可以复制本地文件夹到镜像中:
|
1
|
COPY site1 /var/www/html |
ADD 命令支持添加本地的tar压缩包到容器中指定目录,压缩包会被自动解压为目录,也可以自动下载URL并拷贝到镜像,例如:
|
1
2
|
ADD html.tar /var/wwwADD http://192.168.1.200/html.tar /var/www |
6)CMD 与 ENTRYPOINT
ENTRYPOINT 容器启动后执行的命令,让容器执行表现的像一个可执行程序一样,与CMD的区别是不可以被docker run覆盖,会把docker run后面的参数当作传递给ENTRYPOINT指令的参数。Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效。docker run命令的-entrypoint参数可以把指定的参数继续传递给ENTRYPOINT。
7)挂载数据卷
将apache访问的日志数据存储到宿主机可以访问的数据卷中:
|
1
|
VOLUME ["/var/log/apche2"] |
8)设置容器内的环境变量
使用ENV设置一些apache启动的环境变量:
|
1
2
3
4
5
6
|
ENV APACHE_RUN_USER www-dataENV APACHE_RUN_GROUP www-dataENV APACHE_LOG_DIR /var/log/apche2ENV APACHE_PID_FILE /var/run/apache2.pidENV APACHE_RUN_DIR /var/run/apache2ENV APACHE_LOCK_DIR /var/lock/apche2 |
9)使用 Supervisord
CMD如果只有一个命令,那如果我们需要运行多个服务怎么办呢?最好的办法是分别在不同的容器中运行,通过link进行连接。如果一定要在一个容器中运行多个服务可以考虑用Supervisord来进行进程管理,方式就是将多个启动命令放入到一个启动脚本中。
首先安装Supervisord,添加下面内容到Dockerfile:
|
1
2
|
RUN apt-get install -yqq supervisorRUN mkdir -p /var/log/supervisor |
拷贝配置文件到指定的目录:
|
1
|
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf |
其中supervisord.conf文件需要放在dockertest目录下,文件内容如下:
|
1
2
3
4
5
|
[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:
|
1
|
CMD ["/usr/bin/supervisord"] |
四、从 Dockerfile 创建镜像
在dockertest文件夹中有如下三个文件:
Dockerfile
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
# debian apache2 php5 ssh vim# Version 0.2# 基础镜像FROM debian:latest# 维护者信息MAINTAINER wl1524520@gmail.com# 设置debian的镜像,加快速度RUN echo 'deb http://mirrors.aliyun.com/debian/ jessie main non-free contrib' > /etc/apt/sources.list \&& echo 'deb http://mirrors.aliyun.com/debian/ jessie-proposed-updates main non-free contrib' >> /etc/apt/sources.list \&& echo 'deb http://mirrors.aliyun.com/debian-security/ jessie/updates main non-free contrib' >> /etc/apt/sources.list# 镜像操作命令RUN apt-get -yqq update \&& apt-get install -yqq supervisor openssh-server openssh-client vim \&& apt-get install -yqq apache2 php5 php5-mcrypt php5-mysql php5-imagick php5-json php5-curl \&& apt-get clean # 设置 ssh,root密码为 www.wanglu.infoRUN echo 'root:www.wanglu.info' | chpasswd \&& mkdir /var/run/sshd \&& sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config# 设置 supervisorRUN mkdir -p /var/log/supervisorCOPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf# 拷贝phpinfo.php文件到容器的 /var/www/htmlCOPY phpinfo.php /var/www/htmlENV HOSTNAME docker-testENV APACHE_RUN_USER www-dataENV APACHE_RUN_GROUP www-dataENV APACHE_LOG_DIR /var/log/apache2ENV APACHE_PID_FILE /var/run/apache2.pidENV APACHE_RUN_DIR /var/run/apache2ENV APACHE_LOCK_DIR /var/lock/apache2EXPOSE 22 80# 启动容器命令CMD ["/usr/bin/supervisord"] |
supervisord.conf
|
1
2
3
4
5
6
7
8
9
|
# supervisord configuration[supervisord]nodaemon=true[program:ssh]command=/usr/sbin/sshd -D[program:apache]command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2ctl -D FOREGROUND" |
phpinfo.php
|
1
2
|
<?phpphpinfo(); |
在dockertest目录下使用 docker build 执行创建,-t参数指定镜像名称:
|
1
|
docker build -t dockertest:0.2 . |
docker images 查看创建的新镜像已经出现在了镜像列表中:

由该镜像创建新的容器site2,并映射本地的8080端口到容器的80端口、8022端口到容器的22端口:
|
1
|
docker run -d -p 8080:80 -p 8022:22 --name site2 dockertest:0.2 |
五、运行测试
部分操作截图:

打开测试网页

Docker实战(五)编写Dockerfile的更多相关文章
- Docker应用五:使用Dockerfile部署MongoDB
在Docker容器中部署MongoDB 不做铺垫,直接开撸: 一.软件准备: docker(已安装) MongoDB-3.2.0.tgz 二.准备配置文件mongo.conf port=27017 d ...
- Docker实战(五)之端口映射与容器互联
除了网络访问外,Docker还提供了两个很方便的功能来满足服务访问的基本需求:一个是允许映射容器内应用的服务端口到本地宿主主机;另一个是互联机制实现多个容器间通过容器名来快速访问. 1.端口映射实现访 ...
- 容器化-Docker实战
导读:本文系统性介绍Docker安装.Docker组件.Docker命令.Dockerfile语法和Docker应用,通过上述介绍使我们已经对docker基本操作有一定了解. 一.前言 本文将系统性的 ...
- Docker实战-为镜像添加SSH服务
1.基于docker commit命令创建 Docker提供了docker commit命令,支持用户提交自己对定制容器的修改,并生成新的镜像. 命令格式为:docker commit CONTAIN ...
- 实战docker,编写Dockerfile定制tomcat8镜像,实现web应用在线部署
最初在tomcat上部署web应用的方式,是通过maven的maven-compiler-plugin插件先打成war包,再将war包复制到tomcat的webapps目录下,后来用上了tomcat7 ...
- Docker实战-编写Dockerfile
一.编译镜像 1. 编译镜像 Dockerfile类似于Makfile,用户使用docker build就可以编译镜像,使用该命令可以设置编译镜像时使用的CPU数量.内存大小.文件路径等 语法:doc ...
- Docker 实战—使用 Dockerfile 构建镜像
Dockerfile 指令详解请访问:https://www.cnblogs.com/cloudfloating/p/11737447.html 使用 Alpine Linux 作为基础镜像 Alpi ...
- 【原创】Docker实战 Dockerfile最佳实践&&容器之间通信
官方最佳实践文档 https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#from Docker实战(三十) ...
- Docker自学纪实(五) 使用Dockerfile构建php网站环境镜像
一般呢,docker构建镜像容器的方式有两种:一种是pull dockerhub仓库里面的镜像,一种是使用Dockerfile自定义构建镜像. 很多时候,公司要求的镜像并不一定符合dockerhub仓 ...
- [置顶]
Docker学习总结(1)——Docker实战之入门以及Dockerfile(一)
一.Docker是什么? 首先Docker是软件工业上的集装箱技术 回顾,在没有集装箱出现以前,传统运输行业中,会存在这些问题: 在运输过程中,货物损坏 装卸.运输货物,效率低下 运输手续繁多及运输环 ...
随机推荐
- poj 2828 buy Tickets 用线段树模拟带插入的队列
Buy Tickets Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2 ...
- zoj 3621 Factorial Problem in Base K 数论 s!后的0个数
Factorial Problem in Base K Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onli ...
- Codeforces Round #302 (Div. 2) D - Destroying Roads 图论,最短路
D - Destroying Roads Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544 ...
- SQL Server2008无法修改表结构?
之前一直用SQL Server2005的数据库,最近升级到2008之后发现修改不了表结构,提示: 根据提示,取消“阻止保存要求重新创建表的更改”后就可以了. 具体操作:SQL Server Manag ...
- CentOS 6.9/7通过yum安装指定版本的PostgreSQL扩展PostGIS
一.安装PostGIS扩展插件(24_10) // 安装EPEL源 # rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-rele ...
- PSCollectionView瀑布流实现
[-] 一基本原理 二具体实现 相关数据结构 视图更新方式 relayoutViews方法 removeAndAddCellsIfNecessary方法 select方法 重用数据块视图机制 三使用方 ...
- ASCII表 基本记忆 -- C
/* ASCII表规则记忆 我们仅仅要记住了一个字母或数字的 ASCII 码 (比如记住 A 为 65 , 0 的 ASCII 码为 48 ), 知道对应的大写和小写字母之间差 32. 0 -- 32 ...
- 面试题1:如何实现C++单例模式?
1. 软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径.设计模式中运用了面向对象编程语言的重要特性:封装.继承.多态.真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积 ...
- Supported_Hardware#4G_LTE_cards_and_modems
https://wiki.mikrotik.com/wiki/Supported_Hardware#4G_LTE_cards_and_modems
- word2010图片仅仅显示边框
有两个可能的原因: 1.图片所在段落的行间距被设置成固定值了 解决:选择所在段落,右键选择段落--弹出[段落]设置对话框--把固定行距改为"单倍行距"或其它--确定. 2.显示设置 ...