5 个技巧,让你的 Dockerfile 像个大师! 天天讯息
今天给朋友们分享的是我们的嘉宾- 前端大佬神光的关于 Dockerfile 使用技巧的文章,希望能对大家有所帮助。
以下是大佬原文:
Docker 是一种容器技术,它可以在操作系统上创建多个相互隔离的容器。容器内独立安装软件、运行服务。
(资料图片)
但是,这个容器和宿主机还是有关联的,比如可以把宿主机的端口映射到容器内的端口、宿主机某个目录挂载到容器内的目录。
比如映射了 3000 端口,那容器内 3000 端口的服务,就可以在宿主机的 3000 端口访问了。
比如挂载了 /aaa 到容器的 /bbb/ccc,那容器内读写 /bbb/ccc 目录的时候,改的就是宿主机的 /aaa 目录,反过来,改宿主机 /aaa 目录,容器内的 /bbb/ccc 也会改,这俩同一个。
这分别叫做端口映射、数据卷(volume)挂载。
这个容器是通过镜像起来的,通过 docker run image-name。
比如:
dockerrun-p3000:3000-v/aaa:/bbb/ccc--namexxx-containerxxx-image
通过 xxx-image 镜像跑起来一个叫做 xxx-container 的容器。
-p 指定端口映射,映射宿主机的 3000 到容器的 3000 端口。
-v 指定数据卷挂载,挂载宿主机的 /aaa 到容器的 /bbb/ccc 目录。
这个镜像是通过 Dockerfile 经过 build 产生的。
也就是这样的流程:
一般在项目里维护 Dockerfile ,然后执行 docker build 构建出镜像、push 到镜像仓库,部署的时候 pull 下来用 docker run 跑起来。
基本 CI/CD 也是这样的流程:
CI 的时候 git clone 项目,根据 dockerfile 构建出镜像,打上 tag,push 到仓库。
CD 的时候把打 tag 的镜像下下来,docker run 跑起来。
这个 Dockerfile 是在项目里维护的,虽然 CI/CD 流程不用自己搞,但是 Dockefile 还是要开发者自己写的。
比如我创建一个 nest 项目:
npxnestnewdockerfile-test-pnpm
然后执行 npm run build,之后把它跑起来:
npmrunbuildnode./dist/
这时候访问 http://localhost:3000 可以看到 hello world,说明服务跑成功了:
那如何通过 Docker 部署这个服务呢?
首先,如果你没安装 docker,可以从 下载 docker desktop,它自带了 docker 命令:
跑起来可以看到本地的所有 docker 容器和镜像:
命令行也是可用的:
然后我们来写下 Dockerfile:
FROMnode:18WORKDIR/*.:///RUNnpminstallCOPY..RUNnpmrunbuildEXPOSE3000CMD["node","./dist/"]
FROM node:18 是继承 node:18 基础镜像。
WORKDIR /app 是指定当前目录为 /app
COPY 复制宿主机的 和 lock 文件到容器的当前目录,也就是 /app 下
RUN 是执行命令,这里执行了 npm install。
然后再复制其余的文件到容器内。
EXPOSE 指定容器需要暴露的端口是 3000。
CMD 指定容器跑起来时执行的命令是 node ./dist/。
然后通过 docker build 把它构建成镜像:
dockerbuild-tdockerfile-test:first.
-t 是指定名字和标签,这里镜像名为 dockerfile-test 标签为 first。
然后在 docker desktop 的 images 里就可以看到这个镜像了:
就是现在镜像稍微大了点,有 G。
我们先跑起来看看:
docker run -d -p 2333:3000 --name first-container dockerfile-test:first
-d 是后台运行。
-p 指定端口映射,映射宿主机的 2333 端口到容器的 3000 端口。
--name 指定容器名
然后就可以看到容器部分有了这个容器了:
浏览器访问 http://localhost:2333 就可以访问容器内跑的这个服务:
这就是 Dockerfile 构建成镜像,然后通过容器跑起来的流程。
但是刚才也发现了,现在镜像太大了,有 呢,怎么优化一下呢?
这就涉及到了第一个技巧:
使用 alpine 镜像,而不是默认的 linux 镜像
docker 容器内跑的是 linux 系统,各种镜像的 dockerfile 都会继承 linux 镜像作为基础镜像。
比如我们刚刚创建的那个镜像,点开详情可以看到它的镜像继承关系:
最终还是继承了 debian 的 Linux 镜像,这是一个 linux 发行版。
但其实这个 linux 镜像可以换成更小的版本,也就是 alpine。
它裁剪了很多不必要的 linux 功能,使得镜像体积大幅减小了。
alpine 是高山植物,就是很少的资源就能存活的意思。
我们改下 dockerfile,使用 alpine 的镜像:
node: 是使用 18 版本的 node 镜像,它底层使用 alpine 的基础镜像。
然后 docker build
dockerbuild-tdockerfile-test:second.
这次的 tag 为 second。
然后在 docker desktop 里看下:
好家伙,足足小了 900M。
我们点开看看:
可以看到它的底层 linux 镜像是 。
体积小了这么多,功能还正常么?
我们跑跑看:
dockerrun-d-p2334:3000--namesecond-containerdockerfile-test:second
docker desktop 可以看到这个跑起来的容器:
浏览器访问下,依然是正常的:
alpine 只是去掉了很多 linux 里用不到的功能,使得镜像体积更小。
这就是第一个技巧。
然后再来看第二个:
使用多阶段构建
看下这个 dockerfile,大家发现有啥问题没:
有的同学可能会说:为什么先复制 进去,安装依赖之后再复制其他文件,直接全部复制进去不就行了?
不是的,这两种写法的效果不同。
docker 是分层存储的,dockerfile 里的每一行指令是一层,会做缓存。
每次 docker build 的时候,只会从变化的层开始重新构建,没变的层会直接复用。
也就说现在这种写法,如果 没变,那么就不会执行 npm install,直接复用之前的。
那如果一开始就把所有文件复制进去呢?
那不管 变没变,任何一个文件变了,都会重新 npm install,这样没法充分利用缓存,性能不好。
我们试试看就知道了:
现在重新跑 docker build,不管跑多少次,速度都很快,因为文件没变,直接用了镜像缓存:
dockerbuild-tdockerfile-test:second.
现在我们改下 :
然后重新跑 build:
现在花了 25s,其实是没有重新 npm install 的。
然后改下 :
再跑 docker build
时间明显多了很多,过程中你可以看到在 npm install 那层停留了很长时间。
这就是为什么要这样写:
这里没问题,大家还能发现有没有什么别的问题么?
问题就是源码和很多构建的依赖是不需要的,但是现在都保存在了镜像里。
实际上我们只需要构建出来的 ./dist 目录下的文件还有运行时的依赖。
那怎么办呢?
这时可以用多阶段构建:
FROMnode:.RUNnpminstallCOPY..RUNnpmrunbuild#productionstageFROMnode:=build-stage/app/dist/appCOPY--from=build-stage/app//app//appRUNnpminstall--productionEXPOSE3000CMD["node","/app/"]
FROM 后面添加一个 as 来指定当前构建阶段的名字。
通过 COPY --from=xxx 可以从上个阶段复制文件过来。
然后 npm install 的时候添加 --production,这样只会安装 dependencies 的依赖。
docker build 之后,只会留下最后一个阶段的镜像。
也就是说,最终构建出来的镜像里是没有源码的,有的只是 dist 的文件和运行时依赖。
这样镜像就会小很多。
我们来试试看:
dockerbuild-tdockerfile-test:.
标签为 third。
-f 是指定 Dockerfile 的名字。
然后 desktop 里看下构建出来的镜像:
镜像体积比没有用多阶段构建的时候小了 250 M。
然后跑起来试试看:
这次映射 2335 端口到容器内的 3000 端口。
依然能正常访问:
这就是第二个技巧,多阶段构建。
使用 ARG 增加构建灵活性
我们写一个
();();
打印了环境变量 aaa、bbb
跑一下:
exportaaa=1bbb=2node./
可以看到打印了这俩环境变量:
然后我们写个 dockerfile,文件名是 :
FROMnode:/appCOPY./=${aaa}\bbb=${bbb}CMD["node","/app/"]
使用 ARG 声明构建参数,使用 ${xxx} 来取
然后用 ENV 声明环境变量。
dockerfile 内换行使用 \
之后构建的时候传入构建参数:
dockerbuild--build-argaaa=3--build-argbbb=.
通过 --build-arg xxx=yyy 传入 ARG 参数的值。
点击查看镜像详情,可以看到 ARG 已经被替换为具体的值了:
然后跑起来:
dockerrun--namefourth-containerarg-test
这次就不用 -d 后台运行了,直接看下日志:
可以看到容器内拿到的环境变量就是 ENV 设置的。
也就是说 ARG 是构建时的参数,ENV 时运行时的变量。
灵活使用 ARG,可以增加 dockerfile 的灵活性。
这就是第三个技巧。
CMD 结合 ENTRYPOINT
前面我们指定容器跑起来之后运行什么命令,用的是 CMD:
其实还可以写成 ENTRYPOINT:
这两种写法有什么区别么?
我们来试试:
写个
FROMnode:["echo","光光","到此一游"]
然后 build:
.
然后 run 一下:
dockerruncmd-test
没有指定 --name 时,会生成一个随机容器名。
就是这种:
这不是重点。
重点是用 CMD 的时候,启动命令是可以重写的:
dockerruncmd-testecho"东东"
可以替换成任何命令。
而用 ENTRYPOINT 就不会:
FROMnode:["echo","光光","到此一游"]
docker build:
.
docker run:
dockerruncmd-testecho"东东"
可以看到,现在 dockerfile 里 ENTRYPOINT 的命令依然执行了。
docker run 传入的参数作为了 echo 的额外参数。
这就是 ENTRYPOINT 和 CMD 的区别。
一般还是 CMD 用的多点,可以灵活修改启动命令。
其实 ENTRYPOINT 和 CMD 是可以结合使用的。
比如这样:
FROMnode:["echo","光光"]CMD["到此一游"]
docker build:
.
docker run:
dockerruncmd-testdockerruncmd-test66666
当没传参数的时候,执行的是 ENTRYPOINT + CMD 组合的命令,而传入参数的时候,只有 CMD 部分会被覆盖。
这就起到了默认值的作用。
所以,用 ENTRYPOINT + CMD 的方式更加灵活。
这是第四个技巧。
COPY vs ADD
其实不只是 ENTRYPOINT 和 CMD 相似,dockerfile 里还有一对指令也比较相似,就是 ADD 和 COPY。
这俩都可以把宿主机的文件复制到容器内。
但有一点区别,就是对于 这种压缩文件的处理上:
我们创建一个 aaa 目录,下面添加两个文件:
使用 tar 命令打包:
./aaa
然后写个
FROMnode:.//aaaCOPY.//bbb
docker build 生成镜像:
.
docker run 跑起来:
dockerrun-d--namesixth-containeradd-test
可以看到,ADD 把 给解压然后复制到容器内了。
而 COPY 没有解压,它把文件整个复制过去了:
也就是说,ADD、COPY 都可以用于把目录下的文件复制到容器内的目录下。
但是 ADD 还可以解压 文件。
一般情况下,还是用 COPY 居多。
案例代码上传了 github:
/QuarkGluonPlasma/nestjs-course-code/tree/main/dockerfile-test
总结
Docker 是流行的容器技术,它可以在操作系统上创建多个隔离的容器,在容器内跑各种服务。
它的流程是 Dockerfile 经过 docker build 生成 docker 镜像,然后 docker run 来跑容器。
docker run 的时候可以通过 -p 指定宿主机和容器的端口映射,通过 -v 挂载数据卷到容器内的某个目录。
CI/CD 基本也是这套流程,但是 Dockerfile 是要开发者自己维护的。
Dockerfile 有挺多技巧:
灵活使用这些技巧,可以让你的 Dockerfile 更加灵活、性能更好。
最后,欢迎学编程的朋友们加入鱼皮的,和上万名学编程的同学共享知识、交流进步,学习原创项目并享有答疑指导服务。
往期推荐
标签:
相关阅读
404 Not Found
精彩推荐
404 Not Found
阅读排行
404 Not Found
相关词
- 海军第43批护航编队三亚舰组织舰艇开放日活动|每日头条
- 逆水寒水墨色系时装怎么得 时装获取方法介绍
- 荷兰21两平失主动权_每日消息
- 逆水寒醉卧苍云时装怎么得 醉卧苍云获取方法 世界快播报
- 保护生存之地什么时候出 公测上线时间预告
- 店铺改造官网在哪下载 最新官方下载安装地址-全球新动态
- 结息关账!这几天湖南省直公积金停办线上线下业务 全球快看点
- 晒成绩亮行动,重庆强力推动数字经贸高质量发展
- 中天科技:收购如东和风海上风力发电有限公司20%股权 天天速看
- 逆水寒素问平民最肉装备应该怎么打造
- 每日讯息!赛尔计划雷伊刻印怎么选择-雷伊天赋刻印推荐
- 潮州老字号在中国国际中小企业博览会上“吸睛”无数 全球即时看
- 全球通讯!南瓜面粉可以做的美食_南瓜和面粉的做法大全
- 焦点速读:《逆水寒》断发怎么用 称号断发介绍
- 香草牛仔粒正宗做法?
- 残阳恨心
- 视焦点讯!“双城·纪—亚运之光纪实影像展”在杭州图书馆开幕
- Xbox收购《地狱之刃》开发商花费曝光:1.17亿美元
- 美的电饭煲与苏泊尔电饭煲谁好(美的电饭煲与苏泊尔电饭煲哪个好)
- 《木卫四协议》大型DLC即将推出 新武器“动能锤”加入 全球聚焦
- 新股暗盘 | 药师帮(09885)暗盘收涨30% 每手赚1200港元 天天微速讯
- 华海药业:获盐酸艾司洛尔注射液药品注册证书|世界观热点
- 《最终幻想16》玩家点评 不是最终幻想游戏 全球热推荐
- 天天快消息!官方表示《收获日3》故事将不断扩展 带来更多新内容和挑战
- 每日视讯:中新集团参投杏泽资本四期人民币基金完成备案手续
- 聚焦:《最终幻想16》遭玩家抨击:不是真正的FF系列游戏
- 《前线任务2:重制版》发新预告 缩短读取时间-当前热点
- 惠誉:将秦淮数据(CD.US)“BBB-”长期本外币发行人评级列入负面观察名单
- 环球微速讯:【地评线】荔枝网评:“链”动世界,“太湖之约”期待值拉满
- 反弹OR反转?资金加速涌入港股互联网ETF(513770),份额再创历史新高!
- 各早稻主产区多举措积极应对“三碰头”农业气象灾害
- 《逆水寒》逆水寒雨中奇缘怎么触发 雨中奇缘触发不了
- 上海医保个人账户每个月能打入多少钱(退休+在职)
- 珠海公安:“智慧服务”提升便民利企质效|今日热议
- 世界聚焦:复旦上线中国高校最大云上科研智算平台,校长金力:望更多学生用AI做创新研究
- 听·见丨录取通知书“花式比美”,比“颜值”更重要的是啥 当前热文
- 解决u盘无法识别数据修复应该怎么做
- win10补丁蓝屏解决教程_视焦点讯
- 售价33.5万元,坦克500 Hi4-T上市|聚焦
- 【报资讯】太阳电缆:利润分配股权登记日为2023年7月4日
- 焦点信息:江西机场集团:以主题教育之“笔”描绘职工幸福画卷
- 百事通!漫评:相约“村庄客厅”,奔赴乡村里的“诗与远方”
- 北部湾航空将于7月运营阜阳过夜基地,执飞14条航线并通达8个省会城市
- 全球首台16兆瓦海上风机首支叶片吊装完成
- 每日热门:全球首台16兆瓦海上风机首支叶片吊装完成
- 崩坏星穹铁道罗刹培养材料有什么 详细材料攻略推荐-世界焦点
- 7月1日起,黔江直飞北京首都航线正式恢复
- 滚动:海拔4600米,这里有群“追光者”
- 世界看点:6月27日,海南航空北京—都柏林航线顺利复航
- 天天亮点!重返未来1999水晶头骨怎么选 详细选择攻略
- 中葡股份:中信国安实业集团有限公司累计质押股数约为4.63亿股
- 天天看热讯:如何解决海信电视机hdmi蓝屏无信号
- 林德女孩装扮好玩吗 林德女孩装扮玩法简介 环球热点评
- 每日视讯:南昌机场组织开展网络安全事件应急演练
- 【播资讯】陵水召开2024年财政预算编制工作会议
- 焦点日报:美国华平投资集团与安宏国际资本公司收购Baxter Pharmaceutical Solutions LLC等两家公司股权案
- 江苏江禾高科电子有限公司召回五星钻豹牌电动车充电器 全球微资讯
- 针织棉和纯棉的区别哪个面料贵(针织棉和纯棉的区别)
- 【天天热闻】美甲艺术工厂什么时候出 公测上线时间预告
- 正观视评:霸占电脑不给市民办证?事不关己岂是服务态度 天天观热点
- 信守承诺,山东农银人寿高额赔付212.48万|每日头条
- lululemon第三年发起 “夏日乐挑战” ,升级规模及赛制打造年度社区盛事
- 陵水召开县国土空间规划委员会2023年第四次会议
- 【热闻】华电国际:将根据实际情况适当提高煤炭库存水平应对夏季用电高峰
- primchanikarn(primc)_全球时讯
- 督办成功!污水退了,心情好了!-全球热点
- 天天滚动:2023LPL夏季赛战报:着急下班?Kanavi小代模式再次20分钟血虐NIP
- “好志愿者”伍念喜:以热血守护生命,以爱心收获真心
- 南沙丨培训+演练!南沙街道开展网格安全管理暨消防安全演练活动|环球聚焦
- 2023重庆长寿区面向区外在编在岗教师遴选教育事业单位人员报名人数、拟招聘名额情况一览表
- 书画 | 广东万众/正嘉2023春季拍卖会精品巡展/征集——汕头站-环球通讯
- 太荒仙境传说官网在哪下载 最新官方下载安装地址
- 2023LPL夏季赛战报:JDG疯狂屠杀 20分钟平推NIP拿下赛点
- 黑龙江省市场监督管理局发布关于8批次食品不合格情况的通告(2023年第13期)
- 世界热讯:增材制造产业发展(广州)论坛暨2023年中国增材制造产业年会将于6月28日至29日举行
- 《原子之心》DLC“湮灭本能”预告 8月2日发布
- 世界热议:京东物流与南航物流二期合作开启
- 焦点速看:12333是什么电话号码(12333是什么电话)
- 齐心集团将于7月18日召开股东大会
- 河南省药品监督管理局关于注销医疗器械产品注册证书的公告2023年第42号 焦点快看
- 环球要闻:《生化危机4:重制版》Steam新增7个成就 艾达王DLC将公布
- 多项医保惠民政策7月1日起实施 世界看热讯
- 旗下一基金2年亏近50%,“民间股神”怎么了?_世界快看点
- 分别的意思有几个_呵呵有几个意思
- 华电国际:将根据实际情况适当提高煤炭库存水平应对夏季用电高峰 全球今头条
- 天天观察:东方盛虹:公司将打造成为世界级光伏胶膜原料企业
- 总台记者观察丨“和平”基金不利和平 欧盟再向乌拨军费|全球微资讯
- 广州市房屋建筑工程施工“安全生产月”演练观摩活动举行-天天视点
- 陕天然气:已全面开展燃气安全隐患排查整治活动
- 每日聚焦:LOL新版本免费升级臻彩体验,大量稀有皮肤将升级臻彩插画!
- 珠海中富现7笔大宗交易 均为折价成交
- 第十四届夏季达沃斯论坛今天举行 与会嘉宾:携手合作才能实现互利共赢
- “宁可种树累死,也不能让沙子把我欺负死!”
- 深南电A:当前天然气价格持续高企,发电成本与售电价格倒挂
- dafwcn.dll损坏修复方法
- 防范强降雨!长江防总、长江委发布汛情通报
- 多地为学生开展普通高校志愿填报相关咨询工作|今日热文
- 海拔4600米,这里有群“追光者” 全球速看料
- 天天快看点丨唐人神拟募资不超过3亿,用于生猪全产业链数字智能化升级等项目
- 天天热消息:解决ps2020丢失d3dcompiler_47.dll有哪些方法
- 未来3天天气预报 时讯
- 世界最资讯丨中消协:“6·18”期间消费维权负面信息集中在网络购物、演出票务等
- “上海—西安—克拉玛依”航线7月2日开航_每日热文
- 《长安幻想》醉山打书攻略
- 今日思考:糖尿病常是“阴虚内热”我是如何做到阴阳共济用药的 昨天
- 多地为学生开展普通高校志愿填报相关咨询工作 当前热闻
- 长春高新拟参投成都君蓉康基金
- 曝光!5月高风险运输企业有这些!|焦点简讯
- 泡菜皮特生存什么时候出 公测上线时间预告_焦点滚动
- 【环球播资讯】如何解决电视hdmi蓝屏
- 安装parsec缺少d3d12.dll怎么办 世界时讯
- 公安误录案底,女子找工作政审发现自己被坐过牢
- 快船交易新进展,洛杉矶同城重磅交易!湖人3换1报价乔治
- 环球快资讯:如何解决电脑进入安全模式蓝屏
- 河南考古又有新发现:精美壁画墓现身郑州
- 暑期长线亲子游产品“卷起来” 海边游、边疆游、美食游最俏
- 电动自行车头盔新国标7月施行 旧的还能佩戴?海口明确不处罚
- 水质持续向好 河湖变身“黄金赛道”-天天快讯
- 艺术 | 王宝强新片《八角笼中》在京首映 回归现实题材“冲破命运牢笼”
- 《逆水寒手游》零氪职业选择推荐
- 《阴阳师》百鬼逸闻琢梦修行活动玩法
- 卫星当教具,导师在太空修订论文!太酷啦!
- 邮储银行沿河县支行:兑换残币解民忧 热情服务暖人心
- 环球热点!湖北钟祥:小区旧改赢民心 引出和谐邻里情
- 广东特检院东莞检测院多举措做好特种设备安全隐患排查工作 全球速讯
- 全球今热点:乌克兰和谈最早将于7月进行?中方回应
- 广东特检院东莞检测院协助开展叉车事故应急救援公开演练
- 水鸟翔集 青海湖迎来鸟类繁殖高峰
- 《太上补天卷》仙灵快曝 | 姜子牙
- 小米13 Ultra新搭档明天公布:白色专业摄影套装|即时焦点
- 全球即时:广西来宾市市场监管局务实开展学青会赛前药品安全保障工作
- 国际氢能燃料电池协会秘书长王菊:铂族金属对氢能产业发展不可或缺-世界微速讯
- 【全球聚看点】中央网信办:即日起开展暑期未成年人网络环境整治专项行动
- 瑞丰银行增持两家银行股份,行长张向荣“同步”离职_世界百事通
- 中消协点名五月天演唱会订单异常 每日播报
- 《木卫四协议》全新DLC预告 6月29日开放 播资讯
- 欧盟就实施巴塞尔协议Ⅲ改革达成临时协议
- 远程预付费水电管理系统的工作原理和功能优势
- 国盛证券:煤价进入下行通道 火电盈利有望持续修复 当前焦点
- 世界速读:数读 | 5月汽车进口量下降18%,雷克萨斯ES、宝马X5、奔驰GLB领衔
- 湖北省咸宁市公共检验检测中心与中国农业国际合作促进会战略合作
- RNG零封Up!蕉太狼道心已碎,宁王八胜梦想基本破灭!
- 当前快讯:俄罗斯撤销针对普里戈任的刑事立案
- 广东东莞联合发布《关于遵章守法生产销售使用电动自行车的通告》
- “泳装照简历”热传,多方回应
- 《最终幻想16》通关主线卡进度解决方法|天天讯息
- 《洛奇英雄传》仲夏时节英雄试炼 丰富活动邀您参与|每日观察
- 19.9元!舍得酒业开卖冰淇淋,酒企跨界只为打动年轻人?|每日动态
- 观点:欧盟就实施巴塞尔协议Ⅲ改革达成临时协议
- 《心跳》首播,玉泽演尹素熙主演,吸血鬼题材,有趣的奇幻爱情剧