如何从 Docker 容器里复制或映射文件
Posted on Wed, 25 Dec 2024 11:13:11 +0800 by LiangMingJian
如何从 Docker 容器里复制或映射文件
从容器里复制文件出来
在 Docker 中,通过 cp 命令可以复制文件。
从容器中复制文件时,容器必须处于运行中状态。
执行:docker cp <容器>:<源路径> <本地路径>。
复制单个文件
docker cp <容器名>:/usr/local/test.sh ./
复制文件夹
docker cp <容器名>:/usr/local/test ./
从宿主机复制文件到容器
这部分操作与从容器里复制相反,需要先写本地的文件路径,再写容器内的路径。
执行:docker cp <本地路径> <容器>:<目标路径>
复制单个文件
docker cp ./test.sh <容器名>:/usr/local/test.sh
复制文件夹
docker cp ./tset <容器名>:/usr/local/test
文件映射
在日常使用中,往往我们不会选择上述方式修改容器内的文件,而是通过 volumes 进行文件映射。
在 docker-compose.yml 文件中,我们可以通过如下参数配置 volumes 映射。
version: '3.1'
services:
database:
image: database:8
container_name: database
restart: always
ports:
- "3306:3306"
privileged: true
tty: true
volumes:
- /home/platform/database:/var/lib/mysql
在 volumes 中,依据 - <本地路径>:<容器路径> 来编写配置。
注意,Docker 在启动容器并处理卷映射(volumes)时,会检查宿主机上的目标路径:
- 当宿主机中目标目录或文件不存在的时候(比如第一次运行),Docker 会在宿主机上自动创建该目录,并将容器内的文件自动复制到宿主机新创建的目录中。
- 当宿主机中目标目录或文件已存在的时候(比如再次运行),Docker 此时就不会复制容器内的文件,而是会将宿主机的文件覆盖到容器内。
特别的,在较新版本中,Docker 不再尝试自动初始化内容,以避免意外覆盖用户数据。
即在第一次运行时,较新版本的 Docker 不再会将容器内的文件自动复制到宿主机的目录中。
在新版本 Docker 中,依据官方文档 Bind mounts 中所述:
If you use
--volumeto bind-mount a file or directory that does not yet exist on the Docker host, Docker automatically creates the directory on the host for you. It’s always created as a directory.(如果你使用--volume来绑定挂载一个在 Docker 主机上尚不存在的文件或目录,Docker 会自动在主机上为你创建该目录。它总是以目录的形式创建。)
By default,
--mountdoes not automatically create a directory if the specified mount path does not exist on the host. Instead, it produces an error.(默认情况下,如果主机上不存在指定的挂载路径,--mount不会自动创建目录。相反,它会产生一个错误。)
Docker 容器在初始化 volumes 时,只会创建一个空白目录,如果容器内一个包含文件内容的文件夹被映射到主机,那么主机中最多会自动创建一个相同文件夹,但文件夹内会是空白。
因此,在这种情况下,Docker 的文件映射一般只适用于系统运行中生成文件的存放位置,比如映射数据库,图片,视频等资源文件。
如果确实需要映射一些不在系统运行时生成的文件,比如配置文件,那么就只能先暂时注释掉 volumes 配置,使用 cp 命令从容器中复制文件内容后再恢复 volumes 配置。