【问题标题】:Mounted directory empty with docker-compose and custom Dockerfile使用 docker-compose 和自定义 Dockerfile 挂载目录为空
【发布时间】:2020-01-28 14:35:30
【问题描述】:

我对 Docker 非常(非常)陌生,所以我在尝试。我创建了一个非常基本的 Dockerfile 来引入 Laravel:

FROM composer:latest
RUN composer_version="$(composer --version)" && echo $composer_version
RUN composer global require laravel/installer
WORKDIR /var/www
RUN composer create-project --prefer-dist laravel/laravel site

我的 docker-compose.yml 文件如下所示:

version: '3.7'

services:

    laravel:
        build:
            context: .
            dockerfile: laravel.dockerfile
        container_name: my_laravel
        network_mode: host
        restart: on-failure
        volumes:
            - ./site:/var/www/site

当我运行 docker-compose up 时,会创建 ./site 目录,但内容为空。我已经把它放在 docker-compose 中,因为我打算包括其他东西,比如 nginx、mysql、php 等

命令:

docker run -v "/where/i/want/data/site:/var/www/site" my_laravel

导致相同的行为。

我知道安装成功,因为我修改了我的 dockerfile 并附加了以下两行:

WORKDIR /var/www/site
RUN ls -la

这给了我正确的列表。

这里显然误解了一些东西。任何帮助表示赞赏。

【问题讨论】:

    标签: docker docker-compose dockerfile


    【解决方案1】:

    编辑:所以,我能够让它工作......虽然,它比仅仅指定一个路径稍微困难......

    您可以通过在docker-compose.yml 中指定一个卷来完成此操作。在撰写文件中,目录的路径(在主机上)标记为device。看来路径的根必须是一个实际的卷(可能是共享),但路径的“目标”可以是指定卷上的目录..

    我在我的机器上创建了一个名为 docker 的新卷,但我想您可以使用现有磁盘/卷来执行此操作..

    我在 Mac 上,这个 docker-compose.yml 文件对我有用:

    version: '3.7'
    services:
      nodemon-test:
        container_name: my-nodemon-test
        image: oze4/nodemon-docker-test
        ports:
          - "1337:1337"
        volumes:
          - docker_test_app:/app    # see comment below on which name to use here
    
    volumes:
      docker_test_app:              # use this name under `volumes:` for the service
        name: docker_test_app
        driver: local
        driver_opts:
           o: bind
           type: none
           device: /Volumes/docker/docker_test_app
    

    指定的容器存在于我的 DockerHub..this is the source code 中,以防万一你担心任何恶意。我在两周前创建了它到help someone else on StackOverflow


    在我的机器(主机)上显示来自容器的文件..


    如果您愿意,可以阅读有关 Docker Volume 配置here 的更多信息。


    原始答案:

    看起来你正试图与你的主机共享构建目录。经过一些测试,Docker 似乎会用主机上的路径内容覆盖容器上的指定路径。

    如果您运行docker logs my_laravel,您应该会在/var/www/site 看到有关丢失文件的错误。因此,即使构建成功 - 一旦 Docker 将目录从您的机器 (./site) 安装到容器 (@ 987654335@) 它会用主机上的路径内容 (./site) 覆盖容器内的路径 (/var/www/site) - 这是空的。

    要测试并确保/var/www/site 的内容实际上被覆盖,您可以运行docker exec -it /bin/bash(您可能需要将/bin/bash 替换为/bash)。这将为您提供命令行访问权限容器内。从那里你可以做ls -a /var/www/site..

    此外,您还可以预先准备./site 以在其中包含一个随机测试文件(test.txt 或其他),然后docker-compose up -d,然后从上面的步骤中运行相同的命令docker exec -it ... 并查看是否暂存的 test.txt 文件现在位于容器内 - 这为您提供了明确的证据,即当您运行 volumes 时,主机上的数据会覆盖容器中的数据。

    话虽如此,doing something like this 和共享日志目录都可以工作......容器上指定的卷路径仍然被覆盖,不同之处在于容器正在写入该路径......它不依赖于它用于配置文件/应用程序文件。

    希望这会有所帮助。

    【讨论】:

    • 你说的很对。我定义的任何卷都将被拉入容器中,从而覆盖其中的任何内容。我正在寻找一种使用 CMD 来完成我想要的不同方式,即 - 在首次调用容器时填充绑定目录。
    • @Zakalwe 我想出了如何做到这一点 - 我已经更新了我的答案,并解释了我是如何做到的。
    • 非常感谢!只需要整理一些 Laravel 特定的权限,但这成功了,感谢您对此进行调查。
    猜你喜欢
    • 2020-10-21
    • 1970-01-01
    • 2017-05-09
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    相关资源
    最近更新 更多