Docker之使用Dockerfile创建定制化镜像(四)--技术流ken
前言
在之前的博客《Docker端口映射及创建镜像演示(二)--技术流ken》,演示了如何使用一个现有容器创建一个镜像,以及镜像在阿里云的上传和下载。
但是这样的镜像有很大的局限性,不能根据我们的生产需要进行个性化定制,所以我们急需学习一种能够满足我们需要的制作镜像的工具。
这个时候Dockerfile就出现了。
使用dockerfile指令可以根据自己的需要,制作满足自己生产需要的镜像。
本篇博客将详细讲解如何使用dockerfile制作自己的专属镜像。
Dockerfile简介
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么哪些无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
Dockerfile 是一个文本文件,其内包含了一条条的指令,每一条指令构建一层,
因此每一条指令的内容,就是描述该层应当如何构建
Dockerfile编写注意项
- # 备注
- 指令参数,指令的大小写不敏感
- 第一个非注释行必须是FROM指令
- 编写Dockerfile必须在一个目录下进行,这个目录称之为 工作目录(WORKSPACE)
- Dockerfile文件命令的首字母必须大写
- 制作镜像所要用的文件必须放在工作目录或者工作目录的子目录之下,不能放在父目录
- 可以通过隐藏文件 .dockeringnore 来指定不要放入到镜像中的文件,一行是一个文件,可以用通配符
- 基于dockerfile做镜像,本质上还是基于一个现有的镜像做新镜像
Dockerfile指令详解
1. FROM
作用:FROM 就是指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令
格式:
FROM <registry>:[tag]
FROM <registry>@<digest>
FROM 示例:
第一步:创建工作目录及dockerfile
- [root@ken ~]# mkdir /ken
- [root@ken ~]# cd /ken
- [root@ken ken]# touch Dockerfile
第二步:写入from指令
docker.io:注册表
nginx:仓库
latest:版本号
- [root@ken ken]# cat Dockerfile
- FROM docker.io/nginx:latest
2. LABEL
作用:设定一些元数据
格式:
LABEL 信息
LABEL示例:
- LABEL author "ken"
3. COPY
作用:将工作目录下的文件复制到所做得镜像中的文件系统中
格式:
复制单个文件:COPY <src> <dest>
复制多个文件:COPY [<src> <src> <src>... <dest>]
COPY示例:
- COPY passwd /data/
注意:
- 源文件路径用相对路径,目标一般用绝对路径
- 也可以通配符
- 源文件必须在工作目录或者工作目录的子目录中
- 目标路径可以不存在,会自动创建
- 如果源文件是一个目录,会自动递归复制目录下的文件到目标位置,但是目录自身不会复制
- 如果复制多个文件,或者源文件中用了通配符,那么目标路径必须以 / 为结尾
4. ADD
作用:和COPY类似,可以实现将文件和目录加载镜像中,但是区别是可以实现将tar包解压,也可以实现从网络下载文件到镜像
注意:下载的tar无法解压
格式
ADD <src> <dest>
ADD ["<src>" "<src>" "<src>" "<dest>"]
ADD示例:
- ADD nginx-1.14..tar.gz /data/
5. WORKDIR
作用:相当于执行cd命令。切换目录,为后续的RUN、CMD、ENTRYPOINT 指令配置工作目录。
格式:
WORKDIR 容器目录
WORKDIR示例:
- WORKDIR /pack/nginx/
6. VOLUME
作用:指定数据卷的挂载点
格式:
VOLUME 容器目录
VOLUME示例:
- VOLUME /data/mysql/mysql3306/data
7. EXPOSE
作用:设置Docker容器内部暴露的端口号,如果需要外部访问,还需要启动容器时增加-p或者-P参数进行分配。
格式:
EXPOSE PORT/[PROTOCOL]
EXPOSE示例:
- EXPOSE /tcp
9. ENV
作用:设置环境变量
格式:
ENV var value
ENV var1=value1 var2=value2 ...
注意:
通过ENV所定义的变量是可以传递到容器之中,但是,在创建容器的时候,如果手动指定了变量的值,那么这个值会覆盖掉镜像中原有的值
ENV示例:
- ENV pkgname=nginx-1.14..tar.gz root=/data/mysql/mysql3306/data
10. RUN
作用:基于镜像构建容器时候要执行命令
阶段:第一阶段,也就是构建镜像的时候执行
格式:
RUN 命令
RUN示例:
- RUN tar xf $root$pkgname
11. CMD
作用:定义容器启动以后要默认运行的程序,pid为1的程序
阶段:第二阶段,也就是将镜像构成成容器的时候执行
注意:可以在启动容器的时候用指定的命令替换掉镜像所要执行的命令
CMD指定容器启动是执行的命令,每个Dockerfile只能有一条CMD命令,如果指定了多条,只有最后一条会被执行。如果你在启动容器的时候也指定的命令,那么会覆盖Dockerfile构建的镜像里面的CMD命令
格式:
CMD <命令> 相当于执行的是/bin/sh -c 命令,也相当于执行exec来运行命令
CMD ["<命令>", "<参数>", "<参数>"]
CMD ["<参数>", "<参数>"] <<< 需要借助于ENTRYPOINT指令
CMD示例:
- CMD mkdir /ken
12. ENTRYPOINT
作用:定义容器启动以后要默认运行的程序,pid为1的程序
注意:
在运行RUN的时候所执行的命令无法覆盖ENTRYPOINT中的命令
RUN 后面的命令会被以参数的方式追加到原本要执行的命令的末尾,而不是替换
基于一个镜像,在创建容器的时候,通过传递不同的参数实现创建不同的容器
每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效
格式:
ENTRYPOINT ["执行命令","参数1","参数2"...]
ENTRYPOINT示例:
- ENTRYPOINT [ "curl", "-s", "http://10.220.5.138" ]
13. ARG
作用:定义变量,这个变量是用在第一阶段(构建镜像——build)
格式:
ARG 变量名=变量值
ARG示例:
- ARG name=ken
补充:Dockerfile中ENV 和 ARG的区别
在指定docker build 过程中传参数,要用ARG
在执行docker run的过程中传参数,要用ENV
ARG构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是, ARG 所设置的构建环境的
环境变量,在将来容器运行时是不会存在这些环境变量的
14. USER
作用:指定运行容器时的用户名和UID,后续的RUN指令也会使用这里指定的用户
该用户必须存在于容器的用户空间中(容器的文件系统的中的/etc/passwd中)
格式:
USER <UID>|<USERNAME>
USER示例:
- user ken
15. HEALTHCHECK
作用:docker daemon检查docker容器是否正常,如果异常会将该容器stop
将容器stop的条件
1)主进程停止了
2)主进程工作在了后台
格式:
HEALTHCHECK [options] CMD
options
--interval=#s|m 指定健康检查的时间间隔(例如:30s,30m)
--timeout=#s|m 指定等待响应的超时时间
--start-period=#s|m 指定容器启动多久以后才可以做监控检查
--retries=# 指定重试次数
返回值
0:success
1:unhealth
HEALTHCHECK示例:
- HEALTHCHECK --interval=5m --timeout=1s --retries= CMD curl http://10.220.5.138/ken.html || exit 1
16. SHELL
可以用来指定系统中默认的shell类型
格式:
SHELL ["/bin/sh", "-c"] (linux系统中)
SHELL示例:
- SHELL ["/bin/sh","-c"]
17. STOPSIGNAL
向容器中pid为1的进程发送一个信号,通过这个信号来关闭这个主进程
默认是15信号
格式:
STOPSIGNAL 数值
STOPSIGNAL示例:
- STOPSIGNAL
18. ONBULID
作用:定义一个触发器,指定的命令在构建镜像时并不执行,用来实现当基于这个这个镜像做新镜像的时候要执行的命令
格式:
ONBUILD 其他指令
ONBUILD示例:
- ONBUILD COPY ken /app/
Dokcerfile完整演示创建nginx镜像
根据上面各个指令的介绍,我就直接用上面写的dockerfile进行演示。整个dockerifle内容如下。
- [root@ken ~]# vim /ken/Dockerfile
- FROM docker.io/nginx:latest
- LABEL author "ken"
- COPY ./passwd /data/
- WORKDIR /pack/nginx/
- ENV pkgname=nginx-1.14..tar.gz root=/data/mysql/mysql3306/data/
- COPY nginx-1.14..tar.gz $root
- VOLUME $root
- EXPOSE /tcp
- RUN tar xf $root$pkgname
- CMD nginx -g "daemon off;"
第一步:构建镜像
build:是指根据dockerfile制作镜像
-t:指定一个tag标签
.:表示上下文。你也可以理解为dockfile所在的目录,但是并不是准确的
如果下方出现successfully就表示镜像已经构建成功了
- [root@ken ken]# docker build -t ken:v1- .
- Sending build context to Docker daemon 1.021 MB
- Step / : FROM docker.io/nginx:latest
- ---> 568c4670fa80
- Step / : LABEL author "ken"
- ---> Using cache
- ---> 80e4e5846fd9
- Step / : COPY ./passwd /data/
- ---> Using cache
- ---> 685a7ceb74b3
- Step / : WORKDIR /pack/nginx/
- ---> Using cache
- ---> 0fc65f8c36df
- Step / : ENV pkgname nginx-1.14..tar.gz root /data/mysql/mysql3306/data/
- ---> Using cache
- ---> 3f6038473472
- Step / : COPY nginx-1.14..tar.gz $root
- ---> Using cache
- ---> 0cbff6223d5b
- Step / : VOLUME $root
- ---> Using cache
- ---> b74ac1c36c31
- Step / : EXPOSE /tcp
- ---> Using cache
- ---> 6863a87a61a2
- Step / : RUN tar xf $root$pkgname
- ---> Using cache
- ---> b32ac636a389
- Step / : CMD nginx -g "daemon off;"
- ---> Running in 02308825301d
- ---> 4a91d70a57eb
- Removing intermediate container 02308825301d
- Successfully built 4a91d70a57eb
第二步:查看镜像
可以发现构建的名为ken标签为v1-0的镜像已经存在了
- [root@ken ken]# docker image ls
- REPOSITORY TAG IMAGE ID CREATED SIZE
- ken v1- 4a91d70a57eb minutes ago MB
第三步:启动容器
可以发现基于我们刚才的创建的镜像的容器已经顺利跑起来了。
- [root@ken ken]# docker run -d --name ken3 -d ken:v1-
- 11f492a28b943e619b0ed5d6b19f212f1c9cc47f9bdbe132845e7a7129e5b419
- [root@ken ken]# docker container ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 11f492a28b94 ken:v1- "/bin/sh -c 'nginx..." seconds ago Up seconds /tcp ken3
第四步:登录容器
可以发现我们这个启动的容器里面已经有我们指定的工作目录
复制过来的passwd文件
已经下载并传送到/data下了
- [root@ken ken]# docker exec -it ken3 bash
- root@11f492a28b94:/pack/nginx# ls /data/
- mysql/ passwd
- root@11f492a28b94:/pack/nginx# ls /data/
- mysql/ passwd
- oot@11f492a28b94:/pack/nginx# ls /data/mysql/mysql3306/data/nginx-1.14..tar.gz
- /data/mysql/mysql3306/data/nginx-1.14..tar.gz
这样基于dockerfile自主创建镜像的过程就演示完了,快去自己制作一个属于自己的镜像吧。
Docker之使用Dockerfile创建定制化镜像(四)--技术流ken的更多相关文章
- Docker之使用Dockerfile创建定制化镜像(四)
Dockerfile简介 镜像的定制实际上就是定制每一层所添加的配置.文件.如果我们可以把每一层修改.安装.构建.操作的命令都写入一个脚本,用这个脚本来构建.定制镜像,那么哪些无法重复的问题.镜像构建 ...
- Docker介绍及常用操作演示(一)--技术流ken
Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互 ...
- Docker端口映射及创建镜像演示(二)--技术流ken
前言 在上一篇博客<Docker介绍及常用操作演示--技术流ken>中,已经详细介绍了docker相关内容以及有关镜像和容器的使用命令演示. 现在我们已经可以自己下载镜像,以及创建容器了. ...
- Docker数据卷Volume实现文件共享、数据迁移备份(三)--技术流ken
前言 前面已经写了两篇关于docker的博文了,在工作中有关docker的基本操作已经基本讲解完了.相信现在大家已经能够熟练配置docker以及使用docker来创建镜像以及容器了.本篇博客将会讲解如 ...
- Docker网络(五)--技术流ken
本章内容 1.dokcer默认自带的几种网络介绍 2. 自定义网络 3. 容器间通信 4. 容器与外界交互 docker网络分为单个主机上的容器网络和多个主机上的哇网络,本文主要讲解单个主机上的容器网 ...
- [转]Docker基础-使用Dockerfile创建镜像
本文转自:https://www.cnblogs.com/jie-fang/p/7927643.html 1.基本结构 Dockerfile由一行行命令语句组成,并支持以#开头的注释行.例如: # T ...
- Docker基础-使用Dockerfile创建镜像
1.基本结构 Dockerfile由一行行命令语句组成,并支持以#开头的注释行.例如: # This dockerfile uses the ubuntu image # VERSION 2 - ED ...
- docker学习系列(二):使用Dockerfile创建自己的镜像
dockerfile可以允许我们自己创建镜像,通过编写里面的下载软件命令,执行docker build 即可生成镜像文件. 初尝dockerfile 新建一个目录test,然后进入这个目录,创建一个名 ...
- 使用Dockerfile创建一个tomcat镜像,并运行一个简单war包
docker已经看了有一段时间了,对镜像和容器也有了一个大致了解,参考书上的例子制作一个tomcat镜像,并简单运行一个HelloWorld.war 1.首先下载linux环境的tomcat和jdk, ...
随机推荐
- 使用pdf.js预览实现读取服务器外部文件
不知道大家使用百度网盘的文件预览功能,f12看过控制台没有. 发现百度网盘使用的预览文件功能全是基于开源pdf .js的 接下来正题,我们在使用pdf.js默认是读取发布容器内部的文件,读取外部的文件 ...
- lab-kvm
3)qemu帮助信息 qemu-kvm -h [root@Centos72 libvirt]#qemu-kvm -h QEMU emulator version (qemu-kvm--.el7_5.) ...
- Failed to start end point associated with ProtocolHandler ["http-nio-8080"]
Spring boot运行项目报错,说明8080端口被占用 此时任务管理器结束javax程序即可.
- 背水一战 Windows 10 (101) - 应用间通信: 通过协议打开指定的 app 并传递数据以及获取返回数据, 将本 app 沙盒内的文件共享给其他 app 使用
[源码下载] 背水一战 Windows 10 (101) - 应用间通信: 通过协议打开指定的 app 并传递数据以及获取返回数据, 将本 app 沙盒内的文件共享给其他 app 使用 作者:weba ...
- 「ZJOI2017」树状数组(二维线段树)
「ZJOI2017」树状数组(二维线段树) 吉老师的题目真是难想... 代码中求的是 \(\sum_{i=l-1}^{r-1}a_i\),而实际求的是 \(\sum_{i=l}^{r}a_i\),所以 ...
- 初探系列 — Pharbers用于单点登录的权限架构
一. 前言 就职公司 法伯科技是一家以数据科技为驱动, 专注于医药健康领域的循证咨询公司. 以数据科学家身份, 赋能医药行业. 让每位客户都能享受数据带来的价值, 洞察业务, 不止于数据, 让决策更精 ...
- Android JNI 学习(三):JNI 数据类型和数据结构
本文我们来讨论一下JNI如何将Java类型映射到本机C类型. 一.基本数据类型 如下图表整理了Java基本类型和native对应的关系: Java类型 Native类型 描述 boolean jboo ...
- Python学习笔记【第十篇】:Python面向对象进阶
保护对象的属性 如果有一个对象,当需要对其进行修改属性时,有2种方法 对象名.属性名 = 数据 ---->直接修改 对象名.方法名() ---->间接修改 为了更好的保存属性安全,即不能随 ...
- CSS揭秘—多重边框(二)
前言: 所有实例均来自<CSS揭秘>,该书以平时遇到的疑难杂症为引,提供解决方法,只能说秒极了,再一次刷新了我对CSS的认知 该书只提供了关键CSS代码,虽然有在线示例代码链接,但访问速度 ...
- FTP--FileZilla-主动模式和被动模式
PORT 主动模式: 用户主机一个随机端口连接FTP SERVER的TCP21端口进行协商: 用户主机告诉FTP SERVER,我的XXXX端口已经打开,你可以放心大胆的连过来: 然后FTP SERV ...