一、创建Dockerfile文件

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

二、Dockerfile 基本框架

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

  1. 基础镜像:以哪个镜像作为基础进行制作,用法是FROM 基础镜像名称
  2. 维护者信息:需要写下该Dockerfile编写人的姓名或邮箱,用法是MANITAINER 名字/邮箱
  3. 镜像操作命令:对基础镜像要进行的改造命令,比如安装新的软件,进行哪些特殊配置等,常见的是RUN 命令
  4. 容器启动命令:当基于该镜像的容器启动时需要执行哪些命令,常见的是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,默认为latestRUN命令默认使用/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/www
ADD 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-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

9)使用 Supervisord

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

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

1
2
RUN apt-get install -yqq supervisor
RUN 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.info
RUN echo 'root:www.wanglu.info' | chpasswd \
&& mkdir /var/run/sshd \
&& sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
 
# 设置 supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
 
# 拷贝phpinfo.php文件到容器的 /var/www/html
COPY phpinfo.php /var/www/html
 
ENV HOSTNAME docker-test
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid
ENV APACHE_RUN_DIR /var/run/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
 
EXPOSE 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
<?php
phpinfo();

在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的更多相关文章

  1. Docker应用五:使用Dockerfile部署MongoDB

    在Docker容器中部署MongoDB 不做铺垫,直接开撸: 一.软件准备: docker(已安装) MongoDB-3.2.0.tgz 二.准备配置文件mongo.conf port=27017 d ...

  2. Docker实战(五)之端口映射与容器互联

    除了网络访问外,Docker还提供了两个很方便的功能来满足服务访问的基本需求:一个是允许映射容器内应用的服务端口到本地宿主主机;另一个是互联机制实现多个容器间通过容器名来快速访问. 1.端口映射实现访 ...

  3. 容器化-Docker实战

    导读:本文系统性介绍Docker安装.Docker组件.Docker命令.Dockerfile语法和Docker应用,通过上述介绍使我们已经对docker基本操作有一定了解. 一.前言 本文将系统性的 ...

  4. Docker实战-为镜像添加SSH服务

    1.基于docker commit命令创建 Docker提供了docker commit命令,支持用户提交自己对定制容器的修改,并生成新的镜像. 命令格式为:docker commit CONTAIN ...

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

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

  6. Docker实战-编写Dockerfile

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

  7. Docker 实战—使用 Dockerfile 构建镜像

    Dockerfile 指令详解请访问:https://www.cnblogs.com/cloudfloating/p/11737447.html 使用 Alpine Linux 作为基础镜像 Alpi ...

  8. 【原创】Docker实战 Dockerfile最佳实践&&容器之间通信

    官方最佳实践文档 https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#from Docker实战(三十) ...

  9. Docker自学纪实(五) 使用Dockerfile构建php网站环境镜像

    一般呢,docker构建镜像容器的方式有两种:一种是pull dockerhub仓库里面的镜像,一种是使用Dockerfile自定义构建镜像. 很多时候,公司要求的镜像并不一定符合dockerhub仓 ...

  10. [置顶] Docker学习总结(1)——Docker实战之入门以及Dockerfile(一)

    一.Docker是什么? 首先Docker是软件工业上的集装箱技术 回顾,在没有集装箱出现以前,传统运输行业中,会存在这些问题: 在运输过程中,货物损坏 装卸.运输货物,效率低下 运输手续繁多及运输环 ...

随机推荐

  1. [转]使用popBackStack()清除Fragment

    Clear back stack using fragments up vote88down votefavorite 27 I ported my Android app to honeycomb ...

  2. 浅谈JVM-类加载器结构与双亲委派机制

    一.类加载器结构 1.引导类加载器(bootstrap class loader) 它用来加载Java的核心库(JAVA_HOME/jre/lib/rt.jar),是用原声代码来实现的,并不继承自ja ...

  3. 判断终端是ios还是安卓的一些妙用(附加微信分享图标修改)

    最近遇到一个项目 要求有两个icon(就是下载地址 下载安卓的apk  和ios的安装包) 一开始的方案是 什么设备都显示这两个icon 但是后来老大说这样不好   安卓用户给他下载ios 也不行  ...

  4. 用C语言实现面向对象的开发

    C语言的对象化模型 面向对象的特征主要包括: .封装,隐藏内部实现 .继承,复用现有代码 .多态,改写对象行为 采用C语言实现的关键是如何运用C语言本身的特性来实现上述面向对象的特征. 1.1 封装 ...

  5. 在线分享Oracle尖峰时刻--2014年中秋节尖峰在线福利!

    **********************************************************            2014年中秋节尖峰在线福利!*************** ...

  6. 采用web service传输超大数据

    因为以前也没有做过相关的web service开发,对于Xfire也只是知道有这么一个框架.当然现在它已经变成apache基金会旗下的一个开源项目CXF.不过,现在依旧有很多公司还在用Xfire作we ...

  7. PLSQL初次登录oracle报错处理

    server1上面装了oracle client ,也装了plsql,但是登录了以后,不显示database 和connect as 手工输入正确的用户名和database后报错如下 于是就取消登录 ...

  8. Install Visual Studio Tools for Apache Cordova

    Install Visual Studio Tools for Apache Cordova Visual Studio 2013   This article refers to the Visua ...

  9. [ES6] 01. Intro to ES6 and traceur compiler

    ---恢复内容开始--- ES6 is ECMAScript version 6, which JavaScript is based on. The next version of JavaScri ...

  10. linux CentOS6.5 yum安装mysql 5.6(转载&删改)

    按:下面文章经过我一路测试没有问题,是篇好文,在此感谢作者 别踩我袈裟  .另因原文有些啰嗦,我自己有所删改,并尾后增加了一大段. 出处:https://www.cnblogs.com/renjido ...