- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Docker小白到实战之Dockerfile解析及实战演示由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
使用第三方镜像肯定不是学习Docker的最终目的,最想要的还是自己构建镜像;将自己的程序、文件、环境等构建成自己想要的应用镜像,方便后续部署、启动和维护;而Dockerfile就是专门做这个事的,通过类似简单编码的形式,最终就可以构建出属于自己的镜像,所以必须学起来.
在日常开发过程中,需要编写对应的程序文件,最后通过编译打包生成对应的可执行文件或是类库;这里的Dockerfile文件就好比平时我们编写的程序文件,但内部的语法和关键字并没有程序那么复杂和繁多,相对来说还是很简单的,最后通过docker build命令就可以将对应的程序、文件、环境等构建成镜像啦.
在第一篇文章最后就简单使用了Dockerfile构建了一个镜像,这里重新认识下这个Dockerfile文件,如下图:
Dockerfile就是一个文本文件,但不需要指定后缀类型;文件内容中FROM、WORKDIR、COPY等就是关键字,按照规则写好之后,就可以将指定的文件构建为镜像啦.
构建操作统一由Docker daemon进行,它会先对文件内容语法进行初步验证(语法不对就会返回错误信息),然后逐一运行指令,每次生成一个新的镜像层,直到执行完所有指令,就构建出最终的镜像。 Dockerfile、镜像、容器的关系如下:
总结一下Dockerfile的知识点,
2.1 FROM 关键字 。
指定基础镜像, 就是新镜像是基于哪个镜像构建的.
比如建房子,可以在一块空地开始,也可以在别人打好的基石基础上开始, 甚至可以在别人弄好的毛坯房基础上装修即可.
如果要建房的话,可以FROM 空地,或者FROM 打好的基石,或者 FROM 毛坯房, 反正最后建好房就行,
这里需要注意的是,不管咋样,空地是少不了的;构建镜像也一样,最底层肯定有一个最基础的镜像.
建议使用官方的镜像作为基础镜像,推荐使用Alpine这种类型,因为它是严格控制的,而且体积很小.
用法如下:
2.2 MAINTAINER/LABEL 关键字 。
MAINTAINER 指定维护者的相关信息,也就是构建的镜像是由谁构建的,他的邮箱是什么,
LABLE 就是用于给镜像打标签,以键值对的方式进行指定,相对MAINTAINER 来说比较灵活,可以使用LABLE替代MAINTAINER.
用法如下:
2.3 RUN 关键字 。
构建过程中需要运行的命令, 比如在构建过程中需要执行一条命令下载对应的包,这里就需要用到RUN关键字,
用法如下:
2.4 WORKDIR 关键字 。
根据镜像启动容器时,通常需要进入到容器内部;则可以通过WORKDIR指定进入容器时的目录,
用法如下:
2.5 ENV 关键字 。
可以在构建过程中设置环境变量;就好比平时我们安装完程序,需要配置环境变量,方便访问;ENV关键字就是根据需求可以设置对应的环境变量,
用法如下:
2.6 ADD 关键字 。
将宿主机的资源拷贝进镜像中,会自动解压缩,而且还能从远程宿主机中读取资源并拷贝到镜像中,
用法如下:
2.7 COPY 关键字 。
将宿主机的资源拷贝到镜像中,只支持读取构建所在宿主机的资源。相对于ADD关键字来说更加透明,操作什么就是什么.
用法如下:
2.8 VOLUME 关键字 。
挂载数据卷,之前在常用命令那说到通过命令的方式进行数据卷挂载,在Dockerfile中使用VOLUME指定挂载路径即可,根据构建出来的镜像运行容器时,默认就有构建时挂载的信息.
用法如下:
2.9 EXPOSE 关键字 。
指定运行容器时对外暴露的端口;即根据镜像启动容器时,容器向外暴露端口.
用法如下:
2.10 CMD 关键字 。
指定启动容器时要执行的命令,只有最后一个会生效;即根据镜像启动容器时,容器需要执行啥命令.
用法如下:
2.11 ENTRYPOINT 关键字 。
指定根据镜像启动容器时要执行的命令,可以追加命令;执行时机同CMD.
用法如下:
2.12 ARG 关键字 。
通过ARG指令定义了一个变量;和写代码时定义的变量一样,根据需要,定义就行啦.
用法如下:
2.13 ONBUILD 关键字 。
基于父镜像构建新的镜像时,父镜像的OBUILD会被触发.
这里还是以.NetCore项目构建镜像为例,其他编程语言的项目同理;这次咱们一步一步的来,搞清楚每个命令的使用.
以下关于项目创建和发布的具体细节在第一篇最后就分享了,小伙伴可以参考,这里主要演示Dockerfile关键字.
3.1 准备项目和Dockerfile文件 。
新建一个项目,啥都不需要改,就用默认的接口演示,如下:
Dockerfile内容如下:
记得右键Dockerfile,选择属性,然后设置Dockerfile为始终复制,这样后续更新变动,发布时就会自动拷贝到对应的发布目录.
3.2 以文件的形式发布项目,并连同Dockerfile拷贝到安装好Docker的机器上进行构建(这里还是用我的云服务器),
docker build -t myimage:v1.0 .解析:
3.3 根据构建出来的镜像启动容器,看Dockerfile中的命令效果,
启动容器如下:
ENTRYPOINT ["dotnet", "DockerfileDemo.dll"]这行代码就等同于的项目目录下直接执行 dotnet DockerfileDemo.dll是一样的,目的就是启动我们的项目.
通过docker logs可以查看容器内部的日志,如下:
3.4 丰富化Dockefile文件内容并查看构建之后的细节 。
文件内容如下:
执行如下命令,构建新的镜像:
通过docker logs看看容器日志,如下:
看看数据卷挂载是否成功,进入容器,看根目录下就会多了Logs目录,也可以通过docker inspect 容器 看容器详细信息,如下:
标签也打成功了:
也可以通过docker inspect 镜像查看镜像内部的详细信息,执行命令docker inspect newimage如下:
关于步骤和效果,在Dockerfile注释和图表中已经详细描述.
3.5 CMD和ENTRYPOINT的区别 。
两个命令都是启动容器时指定执行命令和对应的参数,但两者稍有不同,如下:
上面构建出来的newimage镜像用到的是ENTRYPOINT,所以我们先来测试一下ENTRYPOINT,如下:
docker run启动容器时指定了参数 --urls="http://+:9999",容器正常启动,并且参数还能生效,等同于在当前目录直接执行如下命令:
现在把ENTRYPOINT换成CMD试试,如下:
然后重新构建一个镜像试试,测试如下:
如上图,对于CMD而言,如果在运行容器时,后面指定参数,这个参数就会把CMD命令替换掉,不能拼接,导致命令不对,所以报错;但这样就可以执行,如下:
如果在当前构建的上下文目录中不想要一些文件参与构建,可以通过在.dockerignore文件中进行配置,这个和git中的.gitignore一个道理,编写也比较简单,这里就不演示了.
对了,.NetCore的镜像列表可以参照这个地址:https://hub.docker.com/_/microsoft-dotnet-aspnet/,每个镜像都有对应的Dockerfile,感兴趣的小伙伴可以点进去看看,参考参考.
关于Dockerfile的演示就先说那么多,小伙伴们一定要举一反三,上面演示只是一个小例子而已,在正式项目中可以根据需要,编辑出属于符合需求的Dockefile文件,最终构建出方便、好用的镜像,这样开发和运维就和谐了(嘿嘿嘿).
原文链接:https://mp.weixin.qq.com/s/NjByfjyU0uZGSIPptIo2Cw 。
最后此篇关于Docker小白到实战之Dockerfile解析及实战演示的文章就讲到这里了,如果你想了解更多关于Docker小白到实战之Dockerfile解析及实战演示的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
问题情景 混淆群内的小伙伴遇到这么个问题,Mailivery 这个网站登录后,明明提交的表单(邮箱和密码也正确)、请求头等等都没问题,为啥一直重定向到登录页面呢?唉,该出手时就出手啊,我也看看咋回事
实战-行业攻防应急响应 简介: 服务器场景操作系统 Ubuntu 服务器账号密码:root/security123 分析流量包在/home/security/security.pcap 相
背景 最近公司将我们之前使用的链路工具切换为了 OpenTelemetry. 我们的技术栈是: OTLP C
一 同一类的方法都用 synchronized 修饰 1 代码 package concurrent; import java.util.concurrent.TimeUnit; public c
一 简单例子 1 代码 package concurrent.threadlocal; /** * ThreadLocal测试 * * @author cakin */ public class T
1. 问题背景 问题发生在快递分拣的流程中,我尽可能将业务背景简化,让大家只关注并发问题本身。 分拣业务针对每个快递包裹都会生成一个任务,我们称它为 task。task 中有两个字段需要
实战环境 elastic search 8.5.0 + kibna 8.5.0 + springboot 3.0.2 + spring data elasticsearch 5.0.2 +
Win10下yolov8 tensorrt模型加速部署【实战】 TensorRT-Alpha 基于tensorrt+cuda c++实现模型end2end的gpu加速,支持win10、
yolov8 tensorrt模型加速部署【实战】 TensorRT-Alpha 基于tensorrt+cuda c++实现模型end2end的gpu加速,支持win10、linux,
目录如下: 为什么需要自定义授权类型? 前面介绍OAuth2.0的基础知识点时介绍过支持的4种授权类型,分别如下: 授权码模式 简化模式 客户端模式 密码模式
今天这篇文章介绍一下如何在修改密码、修改权限、注销等场景下使JWT失效。 文章的目录如下: 解决方案 JWT最大的一个优势在于它是无状态的,自身包含了认证鉴权所需要的所有信息,服务器端
前言 大家好,我是捡田螺的小男孩。(求个星标置顶) 我们日常做分页需求时,一般会用limit实现,但是当偏移量特别大的时候,查询效率就变得低下。本文将分四个方案,讨论如何优化MySQL百万数
前言 大家好,我是捡田螺的小男孩。 平时我们写代码呢,多数情况都是流水线式写代码,基本就可以实现业务逻辑了。如何在写代码中找到乐趣呢,我觉得,最好的方式就是:使用设计模式优化自己
我们先讲一些arm汇编的基础知识。(我们以armv7为例,最新iphone5s上的64位暂不讨论) 基础知识部分: 首先你介绍一下寄存器: r0-r3:用于函数参数及返回值的传递 r4-r6
一 同一类的静态方法都用 synchronized 修饰 1 代码 package concurrent; import java.util.concurrent.TimeUnit; public
DRF快速写五个接口,比你用手也快··· 实战-DRF快速写接口 开发环境 Python3.6 Pycharm专业版2021.2.3 Sqlite3 Django 2.2 djangorestfram
一 添加依赖 org.apache.thrift libthrift 0.11.0 二 编写 IDL 通过 IDL(.thrift 文件)定义数据结构、异常和接口等数据,供各种编程语言使用 nam
我正在阅读 Redis in action e-book关于semaphores的章节.这是使用redis实现信号量的python代码 def acquire_semaphore(conn, semn
自定义控件在WPF开发中是很常见的,有时候某些控件需要契合业务或者美化统一样式,这时候就需要对控件做出一些改造。 目录 按钮设置圆角
师父布置的任务,让我写一个服务练练手,搞清楚socket的原理和过程后跑了一个小demo,很有成就感,代码内容也比较清晰易懂,很有教育启发意义。 代码 ?
我是一名优秀的程序员,十分优秀!