Dockerfile官方文档: https://docs.docker.com/engine/reference/builder/

获取容器镜像的方法

容器镜像是容器模板,通过容器镜像才能快速创建容器,容器镜像可分为操作系统类和应用类,操作系统类如CentOS,Ubuntu等镜像,应用类的镜像如Nginx,Mysql等镜像,而获取容器镜像的方法主要有以下几种:

  1. 在DockerHub上下载,使用docker pull
  2. 将操作系统中文件系统打包为容器镜像
  3. 将正在运行的容器打包为容器镜像,即docker commit
  4. 通过Dockerfile实现容器镜像的自定义及生成

下面着重讨论Dockrfile打包容器的方法,实现容器的自定义和生成

Dockerfile介绍

是一种能被Docker程序解释的剧本,由一条条指令组成,并且有自己的书写格式和支持的命令,当要在容器镜像中制定自己额外的需求时,只要在Dockerfile上添加或修改指令即可,然后通过docker build生成自定义的容器镜像

指令分类

指令可以分为两类,构建类指令: 用于构建image,其指定的操作不会在运行的image的容器执行(FROM、MAINTAINER、RUN、ENV、ADD、COPY),以及设置类指令: 用于设置image属性,其指定的操作将在运行image的容器中执行(CMD、ENTRYPOINT、USER、EXPOSE、VOLUME、WORKDIR、ONBUILD)

指令说明:

指令 描述
FROM 构建新镜像基于的基础镜像
LABEL 标签
RUN 构建镜像时运行的shell指令
COPY 拷贝文件或目录到镜像中
ADD 解压压缩包并拷贝
ENV 设置环境变量
EXPOSE 声明容器运行的服务端口
WORKDIR 为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录
CMD 运行容器时默认执行,如果有多个CMD指令,最后一个生效
USER 为RUN、CMD、ENTRYPOINT执行命令指定运行用户

指令解释

部分指令详细解释:

FROM

该指令用于指定其后构建新镜像所使用的基础镜像,必须是Dockerfile文件中的首条指令,制定的image可以是官方远程仓库的,也可以位于本地仓库(优先)

FROM <image>:<tag>

example: FROM centos:latest

RUN

该指令用于在构建镜像中执行命令,有以下两种格式:

shell格式

RUN <命令>

example: RUN echo 'hello' > /var/www/html/index.html

exec格式

RUN ["可执行文件","参数1","参数2"]

example: RUN ["/bin/bash","-c","echo hello > /var/www/html/index.html"]

当有多条要执行的命令时,不使用多条RUN,尽量使用&&符号与\符号连接成一行,因为多条RUN命令会让镜像建立多层

CMD

和RUN不同,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令

CMD ["executable","param1","param2"]
CMD ["param1","param2"]
CMD command param1 param2

每个Dockerfile只能有一条CMD命令,如果指定了多条,只有最后一条会被执行,但如果用户启动时指定了运行的命令,则会覆盖掉CMD指定的命令

EXPOSE

用于指定容器在运行时监听的端口

EXPOSE <port> [<port>...]

example: EXPOSE 80 3306 8080

上述运行的端口还要使用docker run运行容器时通过-p参数映射到宿主机的端口

ENV

用于指定一个环境变量

ENV <key> <value>
ENV <key>=<value>

example: ENV JAVA_HOME /usr/local/jdkxxx/

ADD

用于把宿主机上的文件拷贝到镜像中

ADD <src> <dest>

<src>可以是一个本地文件或者本地压缩文件,如果将其写成一个URL,那么ADD就类似wget命令

<dest>该路径可以是容器内的绝对路径,也可以是相对于工作目录的相对路径

COPY

与ADD指令类似,但COPY的源文件只能是本地文件

COPY <src> <dest>

ENTRYPOINT

和CMD指令相似,在Dockerfile只写一条,如果写了多条,则只有最后一条生效

不同点是如果用户启动容器时指定了运行的命令,ENTRYPOINT不会被运行的命令覆盖,而CMD则会被覆盖

ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1 param2

VOLUME

用于将宿主机的目录和容器里的目录进行映射,只指定挂载点,docker宿主机映射的目录为自动生成的

VOLUME ["<mountpoint>"]

USER

设置启动容器的用户,可以是用户名或UID

USER daemon
USER 1001

如果设置了容器以daemon用户去运行,那么RUN、CMD和ENTRYPOINT都会以这个用户去运行镜像,构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户

WORKDIR

设置工作目录,类似于cd命令

WORKDIR /root

Dockerfile基本使用

Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行

构成: 基础镜像信息、维护者信息、镜像操作指令和容器启动时执行命令

生成步骤:

  1. 创建一个文件夹(目录)
  2. 在文件夹中创建Dockerfile文件(并编写)及其他文件
  3. 使用docker build命令构建镜像
  4. 使用构建的镜像启动容器

构建Nginx容器镜像

使用Dockerfile生成Nginx容器镜像

$ mkdir nginxroot
$ cd nginxroot/

创建一个目录,然后进入该目录,写入一个网页文件

$ echo "nginx is running" > index.html

编辑Dockerfile:

vim Dockerfile

编写的Dockerfile如下所示:

FROM centos:centos7

RUN yum -y install wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum -y install nginx
ADD index.html /usr/share/nginx/html/
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
CMD /usr/sbin/nginx

这段Dockerfile在开头首先用FROM声明了基础镜像,之后安装了一系列软件,使用ADD将文件复制进容器,随后使用RUN命令将写入配置文件,使用EXPOSE指定端口,使用CMD指定启动时要运行的命令

随后运行该命令:

$ sudo docker build -t centos7-nginx:v1 .
Sending build context to Docker daemon 3.072kB
Step 1/8 : FROM centos:centos7
---> eeb6ee3f44bd
Step 2/8 : RUN yum -y install wget
---> Using cache
---> 79705f8c6b65
Step 3/8 : RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
---> Using cache
---> e0fff76f8de2
Step 4/8 : RUN yum -y install nginx
---> Using cache
---> 5a5c9e94413b
Step 5/8 : ADD index.html /usr/share/nginx/html/
---> Using cache
---> 50d7b96fbb28
Step 6/8 : RUN echo "daemon off;" >> /etc/nginx/nginx.conf
---> Using cache
---> 43ec3fc42f0b
Step 7/8 : EXPOSE 80
---> Using cache
---> 18f8e9913d9d
Step 8/8 : CMD /usr/sbin/nginx
---> Using cache
---> b03363dfe7b7
Successfully built b03363dfe7b7
Successfully tagged centos7-nginx:v1

容器构建完成,使用docker images即可查看:

$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7-nginx v1 b03363dfe7b7 16 minutes ago 630MB

启动该容器:

$ sudo docker run -d b03
e31be744c5b452c8060d1ff99112ed85f747f1dd3cbf5bdb54ef74a337328c83
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e31be744c5b4 b03 "/bin/sh -c /usr/sbi…" 15 seconds ago Up 14 seconds 80/tcp epic_nash

查看IP地址:

$ sudo docker inspect e31 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",

访问网站:

$ curl http://172.17.0.2
nginx is running

这代表Nginx正常运行

构建Tomcat容器镜像

使用Dockerfile生成Tomcat容器镜像

与Nginx类似,先创建一个目录,在目录中创建一个网站首页文件,因为Tomcat要求JAVA环境,所以同时需要jdk

jdk压缩文件下载链接: https://download.oracle.com/java/18/latest/jdk-18_linux-x64_bin.tar.gz

将压缩文件解压并命名目录为jdk,将其放置在Dockerfile所在目录下

编辑Dockerfile:

FROM centos:centos7

ENV VERSION=8.5.81
ENV JAVA_HOME=/usr/local/jdk
ENV TOMCAT_HOME=/usr/local/tomcat RUN yum -y install wget
RUN wget https://dlcdn.apache.org/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz --no-check-certificate # 下载
RUN tar xf apache-tomcat-${VERSION}.tar.gz # 解压tomcat压缩文件
RUN mv apache-tomcat-${VERSION} /usr/local/tomcat # 移动文件
RUN rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/* # 删除压缩文件 减小镜像体积
RUN mkdir /usr/local/tomcat/webapps/ROOT # 创建网站根目录
ADD ./index.html /usr/local/tomcat/webapps/ROOT # 将网站首页添加到网站目录
ADD ./jdk /usr/local/jdk # 添加jdk文件 # 写入环境变量
RUN echo "export TOMCAT_HOME=/usr/local/tomcat" >> /etc/profile
RUN echo "export JAVA_HOME=/usr/local/jdk" >> /etc/profile
RUN echo "export PATH=${TOMCAT_HOME}/bin:${JAVA_HOME}/bin:$PATH" >> /etc/profile
RUN echo "CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" >> /etc/profile # 刷新环境变量
RUN source /etc/profile
EXPOSE 8080
CMD ["usr/local/tomcat/bin/catalina.sh","run"]

构建镜像: $ sudo docker build -t centos7-tomcat:v1 .

如果下载速度过慢,并且本地已经有tomcat文件,可以直接将文件复制到容器

FROM centos:centos7

ENV VERSION=8.5.81
ENV JAVA_HOME=/usr/local/jdk
ENV TOMCAT_HOME=/usr/local/tomcat ADD ./apache-tomcat-${VERSION} /usr/local/tomcat
RUN rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/*
RUN mkdir /usr/local/tomcat/webapps/ROOT
ADD ./index.html /usr/local/tomcat/webapps/ROOT
ADD ./jdk /usr/local/jdk RUN echo "export TOMCAT_HOME=/usr/local/tomcat" >> /etc/profile
RUN echo "export JAVA_HOME=/usr/local/jdk" >> /etc/profile
RUN echo "export PATH=${TOMCAT_HOME}/bin:${JAVA_HOME}/bin:$PATH" >> /etc/profile
RUN echo "CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" >> /etc/profile RUN source /etc/profile
EXPOSE 8080
CMD ["usr/local/tomcat/bin/catalina.sh","run"]

制作完成后查看镜像列表并启动:

$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7-tomcat v0 c381bb9549b7 About a minute ago 537MB
$ sudo docker run -d c38
c36cb0e050516e8ea4689389c41d8af06bc939787be5aba7d46ebdc38cfbec56

查看IP:

$ sudo docker inspect c36 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",

访问:

$ curl http://172.17.0.3:8080
tomcat is running

可见Tomcat是正常运行的

生成容器镜像优化方法

可以发现,上述打包的镜像大小总要大于官方,这是理所当然的,因为官方制作的是基础类镜像

上述的Dockerfile有许多RUN命令,这样会增加镜像的分层,同时一些缓存也应该被清理,如下有3种方法来减小镜像的大小

  1. 减少镜像分层: 单独的RUN指令都会增加镜像分层,可以把多个合并为一条,使用&&连接指令

  2. 清理无用数据: 一次RUN形成新的一层,如果没有在同一层删除,无论文件最后是否删除,都会带到下一层,所以要在每一层清理对应的残留数据,也要将生成容器镜像过程中部署的应用软件包删除处理,例如使用rm -rf /var/cache/yumyum clean all

  3. 多阶段构建镜像,分段构建镜像

使用Dockerfile构建容器镜像的更多相关文章

  1. Docker中使用多阶段Dockerfile构建容器镜像image(镜像优化)

    使用多阶段构建 预计阅读时间: 6分钟 多阶段构建是守护程序和客户端上需要Docker 17.05或更高版本的新功能.多阶段构建对于那些努力优化Dockerfiles同时使其易于阅读和维护的人来说非常 ...

  2. 使用dockerfile构建nginx镜像

    使用dockerfile构建nginx镜像 docker构建镜像的方法:   commit.dockerfile 1.使用commit来构建镜像: commit是基于原有镜像基础上构建的镜像,使用此方 ...

  3. Dockerfile构建私有镜像

    构建第一个镜像 镜像的定制实际上就是定制每一层所添加的配置,文件.我们可以把每一层修改,安装,构建,操作的命令都写入一个脚本,这个脚本就是Dockerfile.Dockerfile是一个文本文件,其内 ...

  4. Dockerfile构建jar镜像

    dockerDockerfilejar包docker-compose 一.安装docker和compose 二.准备jar包 三.编写配置文件 1. Dockerfile 2. docker-comp ...

  5. Docker学习(六)Dockerfile构建自定义镜像

    Docker学习(六)Dockerfile构建自定义镜像 前言 通过前面一篇文章可以知道怎么去使用一个镜像搭建服务,但是,如何构造自己的一个镜像呢,docker提供了dockerfile可以让我们自己 ...

  6. Dockerfile构建nginx镜像

    Dockerfile构建nginx镜像 [root@bogon ~]# mkdir /opt/docker-file [root@bogon ~]# cd /opt/docker-file/ [roo ...

  7. dockerfile构建Tomcat镜像

    dockerfile构建Tomcat镜像 一.镜像分层概念 二.制作tomcat镜像 2.1.创建分层目录 [root@node2 ~]# mkdir /app/{web/{nginx,tomcat, ...

  8. Docker 使用Dockerfile构建redis镜像

    Dockerfile实现: FROM centos: MAINTAINER hongdada "hongdaqi159505@gmail.com" WORKDIR /home RU ...

  9. Docker 使用Dockerfile构建tomcat镜像

    Dockerfile概念: 镜像的定制实际上就是定制每一层所添加的配置.文件.如果我们可以把每一层修改.安装.构建.操作的命令都写入一个脚本,用这个脚本来构建.定制镜像,那么之前提及的无法重复的问题. ...

  10. 如何使用Dockerfile构建Tomcat镜像并部署war

    我们都知道Docker构建一个镜像有两种方式: 使用`docker commit`命令 使用`Dockerfile`文件和`docker build`命令 那么这两种方式有何区别呢? 相同点:底层实现 ...

随机推荐

  1. 4、jmeter的断言技术

    断言:从反馈的结果来个需求匹配,是不是想要的内容 注:断言必要的时候才用  用过了会影响速度 1.操作步骤: 去选择自己想要响应的文本或者代码或者信息等等..... 2.断言相应大小的字节 3.断言响 ...

  2. Blog作业02

    目录 前言 设计与分析 踩坑心得 改进建议 总结 前言 这三次作业的题目数量虽然增多,但是在题量加大的同时,这三次作业集的难度也相应的下去了,难度降低的同时也保证了作业集题目的质量.这三次的作业的知识 ...

  3. centos 通过yum安装docker-ce报错

    通过yum安装docker-ce报错,是因为本机安装过多次造成的,如下所示,需要解决掉冲突依赖,从新安装 1 从 https://mirrors.aliyun.com/docker-ce/linux/ ...

  4. Kong网关安装自定义插件

    安装自定义插件需要注意kong网关的版本要求!! 下面以安装Skywalking插件为例,要求Kong网关是2.2及以上版本,https://github.com/apache/skywalking- ...

  5. SQL语句用法总结

    use quan56_goods; 使用数据库 show tables; 展示数据表 模糊查询 select * from tb_brand where name like '%林%'; 顺序 书写顺 ...

  6. 实验九 团队作业6:团队项目编码与Alpha冲刺

    项目 内容 课程班级博客链接 2018级卓越班 这个作业要求链接 实验九-团队作业6 团队名称 零基础619 团队成员分工描述 任务1:荣娟,鑫任务2:亚楠,桂婷任务3:亚楠,桂婷任务4:荣娟,鑫任务 ...

  7. Java8-聚合操作

    Java聚合操作(Aggregate Operations)是对一堆数据进行处理的新的操作方法,我们知道,如果想对一堆数据进行处理,比如一个List对象中的数据进行处理,传统的操作就是遍历List数据 ...

  8. ANOMALY: use of REX.w is meaningless (default operand size is 64)

    1.打开注册机:win+ R   输入regedit2.找到目录:计算机\HKEY_LOCAL_MACHINE\SOFTWARE\TEC\Ocular.3\agent\config 并添加值3.新增项 ...

  9. BitBake使用攻略--BitBake的语法知识二

    目录 写在前面 1. BitBake中的任务 2. 任务配置 2.1 依赖 2.1.1 内部任务间的依赖 2.1.2 不同菜谱下的任务间依赖 2.1.3 运行时态下的依赖 2.1.4 递归依赖 2.1 ...

  10. IntelliJ IDEA 下载安装及配置使用教程(图文步骤详解)

    前言 壹哥在前面的文章中,带大家下载.安装.配置了Eclipse这个更好用的IDE开发工具,并教会了大家如何在Eclipse中进行项目的创建和代码编写.运行.但是实际上,在各种IDE开发工具中,Ecl ...