如何用docker-compose挂载tmp目录?Dockerfile为何无法访问挂载的主机目录?
问题原因
你遇到的核心问题是镜像构建阶段和容器运行阶段的生命周期分离:
- docker-compose中
volumes字段定义的挂载,是在容器启动运行时才会生效,将主机目录绑定到容器内。 - 而Dockerfile里的
RUN指令是在构建镜像的过程中执行的,这个阶段还没有创建容器,自然也不会有任何卷挂载生效,所以此时容器内的/tmp/cache目录是空的,找不到主机上的文件。
解决方案
根据你的需求场景,有两种可行的解决方式:
场景1:构建镜像时需要用到该文件(文件需打包进镜像)
如果这个文件是构建镜像的必要依赖,应该通过构建上下文将文件传递到构建环境,再用COPY指令复制到镜像内:
- 确保
somebinary.tar.gz位于docker-compose指定的构建上下文目录(你的配置里context: ..,也就是docker-compose.yml所在目录的上级目录)。 - 修改Dockerfile:
# 先把主机上下文里的文件复制到镜像内的目标路径 COPY somebinary.tar.gz /tmp/cache/ # 再执行处理命令 RUN cat /tmp/cache/somebinary.tar.gz | processor.sh - 重新运行
docker-compose build即可,此时构建阶段就能访问到文件。
场景2:仅容器运行时需要该文件(文件无需打包进镜像)
如果这个文件不需要包含在镜像里,只是运行时才需要使用,那么要把处理逻辑从RUN(构建阶段)移到容器启动阶段,用CMD或ENTRYPOINT指令:
- 修改Dockerfile:
# 将处理逻辑放到容器启动时执行 CMD cat /tmp/cache/somebinary.tar.gz | processor.sh - 保持docker-compose.yml的
volumes配置不变,运行docker-compose up时,卷已经挂载完成,容器启动后就能访问到主机上的/tmp/cache/somebinary.tar.gz文件。
进阶场景:构建时需临时挂载主机目录(不打包文件进镜像)
如果必须在构建阶段使用主机目录的文件,但又不想把文件放进构建上下文(比如文件过大或包含敏感内容),可以使用Docker的构建时挂载功能(需要Docker 18.09+版本支持):
- 修改docker-compose.yml,在
build字段中添加构建时挂载配置:version: "3.9" services: app_test: build: context: .. dockerfile: Dockerfile mounts: - type: bind source: /tmp/cache target: /tmp/cache volumes: - /tmp/cache:/tmp/cache - Dockerfile中的
RUN指令可以直接访问/tmp/cache下的文件,这个挂载仅在构建阶段生效,不会把文件打包进最终镜像。
内容的提问来源于stack exchange,提问作者Cerin
相关产品推荐
相关产品推荐

