我正在为我的项目编写一个
docker-compose.yaml
文件。我已经检查了卷文档here.
我也理解docker中
volume
的概念,我可以挂载一个卷,例如-v my-data/:/var/lib/db
,其中my-data/
是我主机上的目录,而/var/lib/db
是数据库容器内的路径。
我的困惑在于我上面放置的链接。那里有以下示例:
version: "3.9"
services:
db:
image: db
volumes:
- data-volume:/var/lib/db
backup:
image: backup-service
volumes:
- data-volume:/var/lib/backup/data
volumes:
data-volume:
我想知道这是否意味着我必须在主机上创建一个名为
data-volume
的目录? 如果我的计算机上有一个路径为 temp/my-data/
的目录,并且我想将该路径挂载到数据库容器 /var/lib/db
该怎么办?我应该做下面这样的事情吗?
version: "3.9"
services:
db:
image: db
volumes:
- temp/my-data/:/var/lib/db
volumes:
temp/my-data/:
我的主要困惑是底部的
volumes:
部分,我不确定卷名是否应该是我的目录的路径,或者应该只是我给出的字面名称&如果是后一种情况那么给定的怎么可能名称在我的机器上映射为 temp/my-data/
?该示例并未表明 & 是不明确的,以澄清这一点。
有人可以帮我澄清一下吗?
P.S. 我尝试使用上面的 docker-compose 我猜,最终出现错误:
ERROR: The Compose file './docker-compose.yaml' is invalid because:
volumes value 'temp/my-data/' does not match any of the regexes: '^[a-zA-Z0-9._-]+$'
映射卷可以是主机上的文件/目录(有时在文档中称为
bind mounts
),也可以是可以使用 docker volume
命令进行管理的 docker 卷。
docker-compose 文件中的
volumes:
部分指定 docker 卷,即不是文件/目录。您帖子中的第一个 docker-compose 使用了这样的卷。
如果您想映射文件或目录(例如在上一个 docker-compose 文件中),则无需在
volumes:
部分中指定任何内容。
Docker 卷(在
volumes:
部分指定的卷或使用 docker volume create
创建的卷)当然也存储在主机上的某个位置,但 docker 对其进行管理,您通常不需要知道位置或格式是什么.
文档的这一部分很好地解释了它,我认为https://docs.docker.com/storage/volumes/
正如@HansKilian提到的,你不需要同时
volumes
和services.volumes
。要使用 services.volumes
,请将主机目录映射到容器目录,如下所示:
services:
db:
image: db
volumes:
- /host/path/lib/db:/container/path/lib/db
这样,主机上的目录
/host/path/lib/db
将由容器使用,并可在 /container/path/lib/db
处使用。
现在,如果你像我一样,我对虚假示例感到非常困惑,所以假设你的主机上的真实目录是
/var/lib/db
,而你只想在 Docker 中运行 shell 时在 /db
看到它(即,docker exec -it /bin/bash container-id
)。
docker-compose.yaml
看起来像这样:
services:
db:
image: db
volumes:
- /var/lib/db:/db
现在,当您运行 shell、
cd /db
和 ls
时,您将看到与在主机上 cd /var/lib/db
相同的结果。
如果您想使用
volumes
部分来指示要使用的全局卷,您首先必须使用 docker volume create
创建该卷。 Hans 链接的文档包含执行此操作的步骤。 /host/path:/container/path
的语法被 volume-name:/container/path
取代。然后,一旦定义,您就可以将 docker-compose.yaml
更改为更像这样:
services:
db:
image: db
volumes:
- your-global-volume-name:/db
volumes:
your-global-volume-name:
external: true
请注意,我未测试或使用过此配置。我假设它是正确的,基于其他有效的方法以及我在文档中可以识别的一些更改。