以 Dockerfile 长格式从主机挂载卷

Mount volume from host in Dockerfile long format

配置 docker-compose.yml 时,我可以轻松地挂载一个将文件夹从主机映射到容器的卷:

...
    volumes:
      - "/host/folder/:/container/folder/"
...

但是,如果我尝试使用 长语法,那将不再有效:

...
volumes:
      - type: volume
        source: /host/folder
        target: /container/folder/
...

根据docs

source: the source of the mount, a path on the host for a bind mount, or the name of a volume defined in the top-level volumes key. Not applicable for a tmpfs mount.

所以,在冗长的语法中,我似乎必须使用绑定类型来挂载主机路径。这是否有意义,根据语法不同的功能?

此外,根据 docs

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure and OS of the host machine, volumes are completely managed by Docker.

所以,我更喜欢使用卷而不是绑定。我必须为此使用 短语法 吗?

试试这个:

...
services:
  some-service:
    image: some-image
    volumes:
      - my-volume-name:/some-path-in-container
volumes:
  my-volume-name:
    driver: local
    driver_opts:
      type: 'none'
      o: 'bind'
      device: '/my-host-folder'
...

type: 字段说明它是命名的 volumebind 坐骑还是其他一些东西。由于您要挂载主机目录,因此需要在扩展语法中指定 type: bind

volumes:
  - type: bind         # <-- not "volume"
    source: /host/folder
    target: /container/folder/

according to the docs, "volumes are [...] preferred...."

恕我直言,Docker 文档非常热衷于命名卷并掩盖了它们的缺点。由于您无法从 Docker 外部访问命名卷的内容,因此它们更难备份和管理,并且不适合注入配置文件和查看日志等任务。我不会自动访问命名卷,因为 Docker 文档表明它是首选。

version: '3.8'
services:
  some-application:
    volumes:

      # Use a bind mount to inject configuration files; you need to
      # directly edit them on the host
      - type: bind
        source: ./config
        target: /app/config

      # Use a bind mount to read back log files; you need to read them
      # on the host
      - type: bind
        source: ./log
        target: /app/data

      # Use a named volume for opaque application data; you do not
      # need to manipulate files on the host, and on MacOS/Windows
      # a named volume will be faster
      - type: volume
        source: app-data  # when type: volume, this is a volume name
        target: /app/data

      # Do not mount anything over /app or the code in the image.

volumes:
  app-data: