Dockerfile COPY的奇怪行为:自动解包一级目录

记录一下今天遇到的坑:Dockerfile

这两天在部署项目的时候,新加进去了一个驱动,需要将2个文件夹以及1个文件COPY进镜像,大刀阔斧一个Dockerfile就写完了,结果COPY进去的文件有问题,Dockerfile的内容如下(因涉及到商用项目,只复现,正好本地有tomcat9的镜像,就用这个啦)。



😈 复现

FROM tomcat:9
RUN mkdir -p /home/jim/
COPY ./a /home/jim      # COPY 文件夹
COPY ./1.txt /home/jim  # COPY 文件

其中a文件夹下包含a.txt、b.txt两个文件。

可以看出来我是想将a文件夹及其下面的两个文件以及1.txt文件COPY进镜像,但是执行之后却发现了问题,容器中/home/jim下并没有a文件夹,只放着三个文件,目录结构如下:

我想要的:

/home/jim├── a|   ├── a.txt|   └── b.txt└── 1.txt

我得到的

/home/jim├── a.txt├── b.txt└── 1.txt

搜索一番才了解到Docker有个迷之操作:若是COPY的对象是文件夹,则只会COPY里面的文件,忽略文件夹
就这么个问题,找了好久,其实我一开始猜到了,甚至怀疑是不是也有-r这样的参数,但是没去尝试(所以实践出真知,真的要多操作操作)。



👾 修正

将Dockerfile改到这面这样,就可以实现上面的需求:

FROM tomcat:9
RUN mkdir -p /home/jim/a
COPY ./a /home/jim/a
COPY ./1.txt /home/jim
  1. FROM镜像这个不必要解释
  2. 第二步不再是只创建/home/jim,而是/home/jim/a,这样一来的话,/home/jim文件也有了,/home/jim/a文件夹也有了。
  3. COPY ./a文件夹到/home/jim/a,由于COPY是拷贝的文件夹里的文件们,所以这一步是把a.txt和b.txt放进/home/jim/a目录下
  4. COPY 1.txt/home/jim文件夹下

这样一来,容器里面的/home/jim文件夹下就是:

.
├── a
|   ├── a.txt
|   └── b.txt
└── 1.txt


🥥 验证

# 打包
docker build -f Dockerfile -t test:v1 .
# 启动
docker run -d --name test --restart always -p 8080:8080 test:v1
# 进入
docker exec -it test bash


📎 求实

后面又去搜了一下资料,根据资料有偿试了一下,发现只是第一层目录会被「解包」,二级目录及其子文件还是会正常Copy进去的。

通过测试可以发现 COPY/ADD 命令有这么几个规则:

  • ADD 命令和 COPY 命令在复制文件时行为一致
  • 使用 * 作为 COPY/ADD 命令的源时候表示的是 ./*
  • COPY/ADD 命令的源如果是文件夹,复制的是文件夹的内容而不是其本身
  • COPY ./* target 中的 * 会被翻译成如下的逻辑:
COPY ./sub_dir1 target
COPY ./sub_dir2 target
COPY ./file1 target
COPY ./file2 target

文件系统里的文件夹和文件,本质上都是文件,我们熟悉的操作系统的 cp 命令在执行 cp * target 时会把文件夹当成文件一股脑的复制到目标路径下,可以认为复制了文件本身,而 docker 的 COPY/ADD 在复制文件夹时复制的是其内容。

docker 的这种「奇怪」的逻辑已经被诟病许久了,但是似乎还没有要改变的意思,最新的进展可以参考下面两个 issue,在 docker 做出修改之前,只能在写 dockerfile 时候注意一下了。



🖋️ 参考文章

参考文章:「简书:Docker COPY 复制文件夹的诡异行为」

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/61703.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据治理-元数据管理

概念 元数据是关于数据的数据,元数据对于数据管理和数据使用来说是必不可少的。所有大型组织都会产生和使用大量的数据,在整个组织中,不同的人拥有不同层面的数据知识,但没有人知道关于数据的一切。因此,必须将这些信息…

(数学) 剑指 Offer 39. 数组中出现次数超过一半的数字 ——【Leetcode每日一题】

❓ 剑指 Offer 39. 数组中出现次数超过一半的数字 难度:简单 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输…

matlab使用教程(26)—常微分方程的求解

1.求解非刚性 ODE 本页包含两个使用 ode45 来求解非刚性常微分方程的示例。MATLAB 提供几个非刚性 ODE 求解器。 • ode45 • ode23 • ode78 • ode89 • ode113 对于大多数非刚性问题,ode45 的性能最佳。但对于允许较宽松的误差容限或刚度适中的问题&…

DataLoader的使用

示例代码: import torchvision from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriter# 准备的测试数据集 test_data torchvision.datasets.CIFAR10("./dataset", trainFalse, transformtorchvision.transforms.…

控制goroutine 的并发执行数量

goroutine的数量上限是1048575吗? 正常项目,协程数量超过十万就需要引起重视。如果有上百万goroutine,一般是有问题的。 但并不是说协程数量的上限是100多w 1048575的来自类似如下的demo代码: package mainimport ( "fmt" "ma…

2023-08-31力扣每日一题-姜汁水题

链接&#xff1a; 1761. 一个图中连通三元组的最小度数 题意&#xff1a; 选择两两相连的三个点&#xff0c;要求度最小 解&#xff1a; 什么暴力hard 实际代码&#xff1a; #include<bits/stdc.h> using namespace std; int minTrioDegree(int n, vector<vect…

使用 Nginx 搭建文件下载服务器

文章目录 一、基础环境二、适用场景三、方法和步骤四、其他说明 版权声明&#xff1a;本文为CSDN博主「杨群」的原创文章&#xff0c;遵循 CC 4.0 BY-SA版权协议&#xff0c;于2023年8月27日首发于CSDN&#xff0c;转载请附上原文出处链接及本声明。 原文链接&#xff1a;http…

CXL 内存交织(Memory Interleaving)

&#x1f525;点击查看精选 CXL 系列文章&#x1f525; &#x1f525;点击进入【芯片设计验证】社区&#xff0c;查看更多精彩内容&#x1f525; &#x1f4e2; 声明&#xff1a; &#x1f96d; 作者主页&#xff1a;【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0c…

Web后端开发(请求响应)上

请求响应的概述 浏览器&#xff08;请求&#xff09;<--------------------------(HTTP协议)---------------------->&#xff08;响应&#xff09;Web服务器 请求&#xff1a;获取请求数据 响应&#xff1a;设置响应数据 BS架构&#xff1a;浏览器/服务器架构模式。…

uniapp项目实战系列(3):底部导航栏与头部导航栏的配置

目录 系列往期文章&#xff08;点击跳转&#xff09;uniapp项目实战系列(1)&#xff1a;导入数据库&#xff0c;启动后端服务&#xff0c;开启代码托管&#xff08;点击跳转&#xff09;uniapp项目实战系列(2)&#xff1a;新建项目&#xff0c;项目搭建&#xff0c;微信开发工具…

33、Flink之hive介绍与简单示例

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

微信小程序使用本地存储方法wx.setStorageSync()和wx.getStorageSync()

微信小程序的本地存储可以使用wx.setStorageSync()和wx.getStorageSync()方法实现 使用wx.setStorageSync()方法可以将数据以键值对的方式存储到本地存储中&#xff1a; wx.setStorageSync(demo, demo123);获取数据&#xff1a;使用wx.getStorageSync()方法可以从本地存储中获…

「MySQL-05」MySQL Workbench的下载和使用

目录 一、MySQL workbench的下载和安装 1. MySQL workbench介绍 2. 到MySQL官网下载mysql workbench 3. 安装workbench 二、创建能远程登录的用户并授权 1. 创建用户oj_client 2. 创建oj数据库 3. 给用户授权 4. 在Linux上登录用户oj_client检查其是否能操作oj数据库 三、使用…

OpenCV(六):多通道分离与合并

目录 1.多通道分离split() 2.多通道合并merge() 3.Android JNI demo 1.多通道分离split() void cv::split ( InputArray m, OutputArrayOfArrays mv &#xff09; m:待分离的多通道图像。 mv:分离后的单通道图像&#xff0c;为向量vector形式。 2.多通道合并merge…

C++ 友元

朋友可访问自己的东西&#xff0c;大概就这么个意思。即某类的友元类可访问该类的所有变量以及函数&#xff0c;或友元函数可以访问该类的变量以及函数&#xff0c;在朋友眼中没有任何隐藏&#xff0c;可谓时赤裸相对&#xff0c;肝胆相照&#xff0c;生生挚友。 注意&#xf…

聊聊检索增强,LangChain一把梭能行吗?

背景 ChatGPT诞生之初&#xff0c;大家仿佛从中看到了未来&#xff1a;可以拿着大语言模型&#xff08;LLM&#xff09;这把锤子&#xff0c;锤遍业务上的钉子。其中最被看好的场景&#xff0c;莫过于搜索&#xff0c;不仅是微软、谷歌、百度这样的大公司将LLM用到自己的搜索业…

ROS2学习(一):Ubuntu 22.04 安装 ROS2(Iron Irwini)

文章目录 一、ROS2(Iron Irwini)介绍二、ROS2(Iron Irwini)安装1.设置编码2.使能代码库3.安装ROS2 Iron 三、ROS2测试四、ROS2卸载 一、ROS2(Iron Irwini)介绍 官方文档 Iron Irwini版本支持的平台如下&#xff1a; 二、ROS2(Iron Irwini)安装 1.设置编码 sudo apt update…

利用python爬取谷歌趋势某个关键词的每日搜索次数

大家好&#xff0c;我是带我去滑雪&#xff01;本期尝试利用python爬取谷歌趋势某个关键词的每日搜索次数。 目录 1、什么是谷歌趋势&#xff1f; 2、爬取谷歌趋势的搜索次数有何用&#xff1f; 3、代码如何实现&#xff1f; (1&#xff09;导入相关模块 &#xff08;2&a…

Java实现根据关键词搜索京东商品列表数据方法,当当API接口(jd.item_search)申请指南

要通过京东网的API获取商品列表数据&#xff0c;您可以使用京东开放平台提供的接口来实现。以下是一种使用Java编程语言实现的示例&#xff0c;展示如何通过京东开放平台API获取商品列表&#xff1a; 首先&#xff0c;确保您已注册成为当当开放平台的开发者&#xff0c;并创建…

Windows安装单节点Zookeeper

刚学习Dubbo&#xff0c;在Centos7中docker安装的zookeeper3.7.1。然后在启动provider时一直报错&#xff0c;用尽办法也没有解决。然后zookeeper相关的知识虽然以前学习过&#xff0c;但是已经忘记的差不多了。现在学习dubbo只能先降低版本使用了&#xff0c;之后再复习zookee…