Copying files to a container with Docker Compose

DockerCopyDocker ComposeVolumes

Docker Problem Overview


I have a Dockerfile where I copy an existing directory (with content) to the container which works fine:

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 

Screenshot of directory listing with docker exec

But when I use a docker-compose.yml file there is only the directory aw3somevideo and inside aw3somevideo there is nothing.

docker-compose.yml:

 php:
    build: php/
    volumes:
      - ./Frontend/ :/var/www/html/
      - ./Frontend/index.php :/var/www/html/
    ports:
      - 8100:80

Screenshot of empty directory listing

Maybe I do not understand the function of volumes and if that's the case please tell me how to copy my existing files to the container via a docker-compose.yml file.

Docker Solutions


Solution 1 - Docker

Given

    volumes:
      - /dir/on/host:/var/www/html

if /dir/on/host doesn't exist, it is created on the host and the empty content is mounted in the container at /var/www/html. Whatever content you had before in /var/www/html inside the container is inaccessible, until you unmount the volume; the new mount is hiding the old content.

Solution 2 - Docker

Preface: I realize this question is quite old and that the OP may have found a workaround but because I do not see an accurate answer, I felt it appropriate to address the questions posed by the OP as well as any related issues.

First, clarifying the distinction between named volumes and bind mounts. The former will allow you to see, from outside the container, files that already exist in the container location whereas the latter will not. In essence, bind mounts operate very much like when mounting a volume in xNIX meaning that any files already in the mount location will be masked after a device is mounted - think of it as an overlay.

Next, when you specify ./Frontend/ :/var/www/html/, you are specifying a bind mount which is why when you look in ./Frontend on the host-side, all of the files you expect to see are gone. If I understand your end-goal correctly, you want to have the files in /var/www/html/ within the container be accessible via the exact same location outside of the container. If so, then you probably want to use a named volume along with a user-specified mount point as follows:

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

php:
    build: php/
    volumes:
      - Frontend:/var/www/html/

Be aware that without the driver_opts listed above, the named volume will still exist but the host-side location will be in the Docker area. This is typically something like /var/lib/docker/volumes or similar. The exact location can be found in the Mounts section of the docker inspect command.


Example

Here is a similar setup on my PiHole lab host.

docker-compose.yml (abbreviated)

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/'

Output of sudo docker inspect, Mount section only (abbreviated)

"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",
   }
]

Container file list: /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

Host-side file list: /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

Solution 3 - Docker

On the Dockerfile change COPY to ADD. it is the way to copy directories and not files

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTheDoctorView Question on Stackoverflow
Solution 1 - DockerBernardView Answer on Stackoverflow
Solution 2 - DockertledingView Answer on Stackoverflow
Solution 3 - DockerJulianView Answer on Stackoverflow