Docker:绑定安装的奇怪行为 [英] Docker: Strange behaviour of bind mount

查看:49
本文介绍了Docker:绑定安装的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个撰写文件:

version: "3"
services:

  db:
    image: postgres:12.5
    ports:
      - "15432:5432"
    restart: always  
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: test
    volumes:
      - ./postgres-data:/var/lib/postgresql/data

  backend:
    image: backend
    depends_on:
      - db
    restart: always
    ports:
      - "6969:8000"
    volumes:
      - ./app:/app

当我运行docker-compose启动2个容器时,我注意到:

When I run docker-compose up to start the 2 containers, I notice that:

  • Docker自动创建目录postgres-data,并将/var/lib/postgresql/data 的内容从容器传输到主机目录 postgres-data
  • 使用后端服务,Docker还会自动创建目录./app,但不是将/app目录的内容(从容器)转移到主机中的./app目录,而是执行了 相反 : 它将内容从主机的./app目录传输到容器中的/app .

这两种服务都使用绑定安装,据我了解:绑定安装始终将内容从主机目录传输到容器.但这在数据库服务的情况下不会发生

Both service uses bind mount, and as I understand: bind mount always transfer the content from the host directory to the container. But this does not happen in the case of the db service

那我在哪里理解错了?

预先感谢

推荐答案

什么都不会转移".主机目录的内容总是隐藏基础映像中的内容,并且一旦容器启动,主机目录和容器目录就相同".一侧的书写应该在另一侧可见.

Nothing ever gets "transferred". The contents of the host directory always hide what was in the underlying image, and once the container has started, the host and container directories are "the same"; writes in one side should be visible in the other.

尤其是Docker Hub数据库映像知道在启动时会查看其数据目录.顺序大致如下:

The Docker Hub database images in particular know to look at their data directories at startup time. The sequence is roughly like this:

  1. Docker创建一个容器,主机的 $ PWD/postgres-data 目录替换容器中的/var/lib/postgresql/data .
  2. postgres 图像的入口点脚本查看数据目录,并发现它完全为空.然后,它将创建一个新数据库并运行任何首次初始化脚本.由于该目录是绑定安装的主机目录,因此该内容在主机上也是可见的.
  3. 无论其数据目录是什么,数据库都可以正常启动.
  1. Docker creates a container, with the host's $PWD/postgres-data directory replacing /var/lib/postgresql/data in the container.
  2. The postgres image's entrypoint script looks at the data directory and sees it is totally empty. It then creates a new database and runs any first-time-initialization scripts. Since that directory is a bind-mounted host directory, this content is also visible on the host.
  3. The database starts up normally with whatever its data directory is.

这项工作是在容器启动时在已挂载的目录上完成的,因此它也恰好在主机上可见.(如果您 docker运行--rm -it --entrypoint/bin/sh postgres 并绕过其入口点脚本环顾四周,您可能会发现/var/lib/postgresql/data 目录完全为空;没有任何内容可以传输到主机".

This work is done on the mounted directory at container startup time, so it happens to be visible on the host as well. (If you docker run --rm -it --entrypoint /bin/sh postgres and look around, bypassing its entrypoint script, you'll probably find the /var/lib/postgresql/data directory is totally empty; there is nothing there to be "transferred to the host".)

这也意味着您在应用程序容器的/app 目录上的绑定安装会隐藏Dockerfile所做的任何事情;如果您运行一个生成序列,它将丢失,并且如果主机和容器中的目录布局不相同,则将出现不可复制的问题.这进一步意味着您不能直接使用卷将文件复制到映像之外.您必须运行一个运行 cp 命令的容器.

This also means that your bind mount over the application container's /app directory hides whatever the Dockerfile does; if you run a build sequence it will get lost, and if the directory layouts in the host and container aren't identical, you will have non-reproducible problems. This further means you can't directly use volumes to copy file out of an image; you have to run a container that runs a cp command.

这篇关于Docker:绑定安装的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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