我正在尝试dockerize一个PHP应用程序。在dockerfile中,我下载存档,提取它,等等。

一切都很好。但是,如果发布了一个新版本,并且我更新了dockerfile,我必须重新安装应用程序,因为config.php会被覆盖。

因此,我认为我可以将该文件作为卷挂载,就像对数据库所做的那样。

我尝试了两种方法,用音量和直接路径。

docker-compose:

version: '2'
services:
  app:
    build: src
    ports:
      - "8080:80"
    depends_on:
      - mysql
    volumes:
      -  app-conf:/var/www/html/upload
      -  app-conf:/var/www/html/config.php
    environment:
      DB_TYPE: mysql
      DB_MANAGER: MysqlManager

  mysql:
    image: mysql:5.6
    container_name: mysql
    volumes:
      - mysqldata:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD:
      MYSQL_DATABASE:
      MYSQL_USER:
      MYSQL_PASSWORD:

volumes:
  mysqldata:
  app-conf:

这导致了错误:

我尝试用一个给定的路径,作为一个挂载的卷。

/src/docker/myapp/upload:/var/www/html/upload
/src/docker/myapp/upload:/var/www/html/config.php

然而,这两种方法都不起作用。对于挂载的卷,我看到创建了上传。

但它失败了:

/var/www/html/config.php\"造成\"不是目录\""

如果我用

/src/docker/myapp/upload/config.php:/var/www/html/config.php

Docker创建upload文件夹,然后创建config.php文件夹。不是文件。

或者是否有另一种方法来持久化配置?


当前回答

在windows中, 如果你需要在docker-compose中使用a ${PWD} env变量。Yml,你可以在docker-compose的同一个目录下创建一个。env文件。Yml文件然后手动插入文件夹的位置。

CMD (pwd_var.bat):

echo PWD=%cd% >> .env

Powershell (pwd_var.ps1) :

$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'; echo "PWD=$(get-location).path" >> .env

docker-compose .env变量有更多好的特性: https://docs.docker.com/compose/reference/envvars/特别是COMPOSE_CONVERT_WINDOWS_PATHS env变量,它允许docker compose接受带有“\”的windows路径。

当您想要在windows上共享一个文件时,该文件必须在与容器共享之前存在。

其他回答

对我来说有效的方法是使用绑定坐骑

  version: "3.7"    
  services:
  app:
    image: app:latest
    volumes:
      - type: bind
        source: ./sourceFile.yaml
        target: /location/targetFile.yaml

感谢mike breed的回答:使用docker-compose从卷中装入单个文件

您需要使用“长语法”来表示使用volumes键的绑定挂载:https://docs.docker.com/compose/compose-file/compose-file-v3/#long-syntax-3

对我来说,问题是我指定了不正确的源文件。

这里有一个例子:

 robert ❱ ~ ❱ docker run --rm -it -v "${PWD}/non-existant:/root/destination" -w /root --entrypoint /usr/bin/ls ubuntu -lad destination
drwxr-xr-x 2 root root 64 Mar 29 05:54 destination
 robert ❱ ~ ❱ touch exists
 robert ❱ ~ ❱ docker run --rm -it -v "${PWD}/exists:/root/destination" -w /root --entrypoint /usr/bin/ls ubuntu -lad destination
-rw-r--r-- 1 root root 0 Mar 29 05:58 destination
 robert ❱ ~ ❱

TL;DR -这可能是你的拼写,就像我的拼写一样。

2022年答案,在Mac上使用Minikube/Hyperkit docker和docker Compose

由于我不再使用Docker Desktop,我经历了许多类似于minikube“Docker in Docker (dind)”范例的问题…

山minikube 使用绝对路径

例如,最简单的方法是安装确切的回家路径……

minikube mount $HOME:/Users/<you>

... keeps running...

docker-compose.yaml

volumes:
      - /Users/<you>/path/to/file.yaml:/somedir/file.yaml

我在Windows上也遇到了同样的问题,Docker 18.66.1 -ce-win73(19507)。

通过Docker设置面板删除并重新添加共享驱动器,一切都恢复正常了。

以上答案均正确。

但是有一件事我发现非常有帮助的是,挂载文件应该提前存在docker主机内,否则docker将创建一个目录。

例如:

/a/file/inside/host/hostFile.txt:/a/file/inside/container/containerFile.txt

hostFile.txt应该提前存在。 否则你会收到这个错误:containerFile.txt是一个目录