“体积"是如何变化的?用docker-compose覆盖docker镜像的原始文件? [英] How does "volumes" override the docker image's original files with docker-compose?

查看:45
本文介绍了“体积"是如何变化的?用docker-compose覆盖docker镜像的原始文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们使用以下 docker-compose.yml :

version: '2'
services:
   db:
     image: mysql:5.7
     volumes:
       - ./mysql:/var/lib/mysql                # <- important
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress
   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     volumes:
       - ./wp:/var/www/html                    # <- important
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress

我注意到:

  • 做事

mkdir wp
docker-compose up
# create a basic Wordpress website from the browser
# stop the containers from the command-line with CTRL+C

然后, ./wp/(最初为空)被新的Wordpress文件(**)填充.这是正常的.

then, ./wp/ (initially empty) is filled with the new Wordpress files (**). This is normal.

那我们就做

 docker rm wordpress_1 db_1   # remove the existing containers but keep 
                              # ./wp/ as it has been created in the previous step (**)
 docker-compose up

在重新创建容器期间, ./wp/ 不会被新的Wordpress文件覆盖,而是上一步(**)中的先前文件被覆盖保持!为什么?

During the re-creation of the containers, ./wp/ is not overwritten with new Wordpress files, instead the previous files from previous step (**) are kept! Why?

如何神奇地知道应该写入 new Wordpress文件,而应该保留先前的文件?

How does it magically know that new Wordpress files should not be written, but that instead, the previous files should be kept?

问题: docker 如何确定 volumes 中列出的/hostdir/:/containerdir/是否应覆盖哪些文件是否已经存在于原始docker映像中?

Question: How does docker decide if /hostdir/:/containerdir/ listed in volumes: should override the files which are already present in the original docker image, or not?

推荐答案

使用始终语法的绑定安装会覆盖图像中存在的文件.这与普通的Linux mount (8)命令具有相同的作用:如果在源目录的一部分上挂载USB磁盘之类的东西,则挂载设备的内容将隐藏文件系统中的原始内容.,并且所有读写操作都使用已安装的设备.

Bind mounts with that syntax always overwrite the files that are present in the image. This acts the same way as the normal Linux mount(8) command: if you mount something like a USB disk over part of your source directory, the contents of the mounted device hide what was originally in the filesystem, and all reads and writes use the mounted device instead.

当容器启动时,这意味着它可以查看其数据目录是否为空,如果是,则在其中安装一些初始数据.您引用 Docker Hub wordpress 图片;具有入口点脚本有明确的检查

When the container starts up, this means it can look to see if its data directory is empty, and if it is, install some initial data there. You cite the Docker Hub wordpress image; that has an entrypoint script that has an explicit check

if [ ! -e index.php ] && [ ! -e wp-includes/version.php ]; then
    echo >&2 "WordPress not found in $PWD - copying now..."
    # ... some code that creates sourceTarArgs and targetTarArgs ...
    tar "${sourceTarArgs[@]}" . | tar "${targetTarArgs[@]}"
    echo >&2 "Complete! WordPress has been successfully copied to $PWD"
fi

mysql 图像具有类似的检查,以查看其数据目录是否为空.如果是,它将进行首次初始化,包括处理/docker-entrypoint-initdb.d 目录;如果不是,则假定那里已有数据,并完全跳过初始化步骤.

The mysql image has a similar check to see if its data directory is empty. If it is, it does its first-time initialization, including processing the /docker-entrypoint-initdb.d directory; if it isn't, it assumes there is pre-existing data there and completely skips the initialization step.

通常,您应该尝试为实际数据保留绑定装载和类似的卷,而不是在此处复制代码.就 wordpress 映像而言,由于它在卷中复制了应用程序,因此,如果您尝试升级基础映像,将会发生的情况并不十分明显:该卷具有优先级并进行升级可能会被忽略.

In general you should try to reserve bind mounts and similar volumes for actual data, and not copy your code there. In the case of the wordpress image, since it makes a copy of the application in the volume, it's not totally obvious what would happen if you tried to upgrade the underlying image: the volume takes precedence and the upgrade could get ignored.

命名Docker卷(与绑定安装不同)将从底层映像复制内容,但如果是命名卷而不是其他类型的安装,则 >在Docker上正确(在Kubernetes中不是),并且如果卷完全为空(仅是第一次运行容器),则仅 .避免依赖此行为,因为它不是特别可移植,并且会忽略基础映像中的更新.

Named Docker volumes (as distinct from bind mounts) will copy content from the underlying image, but only if it's a named volume and not some other kind of mount, only on Docker proper (not in Kubernetes), and only if the volume is totally empty (it's the very first time you've run the container). Avoid relying on this behavior, since it's not especially portable and ignores updates in the underlying image.

这篇关于“体积"是如何变化的?用docker-compose覆盖docker镜像的原始文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆