使用Docker Compose将文件复制到容器

The*_*tor 62 copy volumes docker docker-compose

我有一个Dockerfile地方,我将现有目录(含内容)复制到容器,工作正常:

Dockerfile

FROM php:7.0-apache
COPY Frontend/ /var/www/html/aw3somevideo/
COPY Frontend/ /var/www/html/

RUN ls -al /var/www/html
RUN chown -R www-data:www-data /var/www/html 
RUN chmod -R 755 /var/www/html 
Run Code Online (Sandbox Code Playgroud)

使用docker exec的目录列表的屏幕截图

但是,当我使用docker-compose.yml文件时,只有目录aw3somevideo,里面aw3somevideo没有任何内容.

docker-compose.yml:

 php:
    build: php/
    volumes:
      - ./Frontend/ :/var/www/html/
      - ./Frontend/index.php :/var/www/html/
    ports:
      - 8100:80
Run Code Online (Sandbox Code Playgroud)

空目录列表的屏幕截图

也许我不明白它的功能,volumes如果是这种情况,请告诉我如何通过docker-compose.yml文件将现有文件复制到容器中.

Ber*_*ard 47

2017年4月更新

自从我写完原始答案以来,这种行为发生了变化.现在一致的是,右侧是否指定了类似于命名的卷myvolume或者主机上的路径/var/lib/myapp.例如

    volumes:
      - /dir/on/host:/var/www/html
Run Code Online (Sandbox Code Playgroud)

如果/dir/on/host不存在,则在主机上创建它,并将空内容安装在容器中/var/www/html.无论/var/www/html以前是什么都无法进入.

----老答案-----------

volumes:docker-compose中的部分将覆盖/var/www/html目录中的任何内容.

主要有两种情况:

  1. 卷存在

    在这种情况下,卷的内容会掩盖dst目录中的任何内容.

    例如:

    volumes:
      - /dir/on/host:/var/www/html
    
    Run Code Online (Sandbox Code Playgroud)
  2. 该卷不存在

    如果myvolume不存在(例如命名卷),/ var/www/html的内容将在第一次复制到卷

    volumes:
      - myvolume:/var/www/html
    
    Run Code Online (Sandbox Code Playgroud)

在案例2中,如果您尝试在某个容器上再次安装相同的卷,则它将遵循案例1.

    volumes:
      - myvolume:/var/www/html
Run Code Online (Sandbox Code Playgroud)

在这种情况下(假设已经创建了myvolume),/ var/ww/html的内容将被其中的任何内容覆盖(阴影)myvolume.

官方文档详细介绍https://docs.docker.com/compose/compose-file/#/volumes-volume-driver

  • 是否有可能,在最近的 docker 版本中,即使“var/www/html/”的内容不存在,也不会再复制到“/dir/on/host”?第一次启动容器时,有没有办法将数据从 docker-container 强制复制到主机? (3认同)
  • @Tarator 是的,确实,右侧不再复制到主机。我会更新答案。至于在容器启动时复制的方法,您可以使用类似这样的命令覆盖启动命令 `docker run -v /dir/on/host:/hostdir php sh -c "cp -rp /var/www/html/* /hostdir && 执行 myapp"`. 不要忘记使用 `exec` 来调用最终命令,以便为它分配 PID1。这将确保 myapp 收到终止信号(例如 Ctrl-C)。 (2认同)

tle*_*ing 19

前言:我意识到这个问题已经很老了,OP可能已经找到了解决方法,但因为我没有看到准确的答案,所以我认为解决OP提出的问题以及任何相关问题是适当的。

首先,澄清命名卷绑定挂载之间的区别。前者允许您从容器外部查看容器位置中已存在的文件,而后者则不允许。本质上,绑定挂载的操作与在 xNIX 中挂载卷时非常相似,这意味着挂载位置中已有的任何文件都将在挂载设备后被屏蔽 - 将其视为覆盖。

接下来,当您指定 时,您正在指定绑定安装,这就是为什么当您在主机端./Frontend/ :/var/www/html/查看时,您期望看到的所有文件都消失了。./Frontend如果我正确理解您的最终目标,您希望可以/var/www/html/通过容器外部的完全相同的位置访问容器内的文件。如果是这样,那么您可能希望使用命名卷以及用户指定的安装点,如下所示:

volumes:
  Frontend:
    driver: local
    driver_opts:
      type: 'none'
      o: 'bind'
      device: '/var/www/html'

php:
    build: php/
    volumes:
      - Frontend:/var/www/html/
Run Code Online (Sandbox Code Playgroud)

请注意,如果没有driver_opts上面列出的内容,命名卷仍将存在,但主机端位置将位于 Docker 区域中。这通常是/var/lib/docker/volumes类似的东西。Mounts确切的位置可以在命令部分找到docker inspect


例子

这是我的 PiHole 实验室主机上的类似设置。

docker-compose.yml (缩写)

volumes:
  etc-pihole:
  etc-dnsmasq.d:
  etc-unbound:
    driver: local
    driver_opts:
      type: 'none'
      o: 'bind'
      device: '/home/dockeruser/ct5/etc-unbound'

services:
  pihole:
    container_name: asbuilt_ct5
    hostname: pb-asbuilt-5
    volumes:
         - './etc-pihole:/etc/pihole/'
         - './etc-dnsmasq.d:/etc/dnsmasq.d/'
         - 'etc-unbound:/etc/unbound/'
Run Code Online (Sandbox Code Playgroud)

sudo docker inspect,部分的输出Mount (缩写)

"Mounts": [
   {
      "Type": "bind",
      "Source": "/home/dockeruser/ct5/etc-dnsmasq.d",
      "Destination": "/etc/dnsmasq.d",
   },
   {
      "Type": "bind",
      "Source": "/home/dockeruser/ct5/etc-pihole",
      "Destination": "/etc/pihole",
   },
   {
      "Type": "volume",
      "Name": "ct5_etc-unbound",
      "Source": "/var/lib/docker/volumes/ct5_etc-unbound/_data",
      "Destination": "/etc/unbound",
      "Driver": "local",
   }
]
Run Code Online (Sandbox Code Playgroud)

容器文件列表:/etc/unbound

root@pb-asbuilt-5:/# ls /etc/unbound
unbound.conf  unbound.conf.d  unbound_control.key  unbound_control.pem  unbound_server.key  unbound_server.pem
Run Code Online (Sandbox Code Playgroud)

主机端文件列表:/home/dockeruser/ct5/etc-unbound

[dockertest-srv1] > ls /home/dockeruser/ct5/etc-unbound
unbound.conf  unbound.conf.d  unbound_control.key  unbound_control.pem  unbound_server.key  unbound_server.pem
Run Code Online (Sandbox Code Playgroud)


ala*_*mar 8

Docker Compose 中没有在部署期间将文件从主机复制到容器的功能。您只能使用绑定挂载,从而可能会产生一些问题(如果目标已存在于容器中,它将被隐藏,如果在部署后删除源,则容器将正常运行,但在重新启动时失败)。

Compose 项目拒绝的复制文件功能的书面记录:

https://github.com/docker/compose/issues/2105

https://github.com/docker/compose/issues/5523