I am new to docker
so I am certain I am doing something wrong. I am also not a php developer
but that shouldn’t matter in this case.
I am using a drupal
docker image which has data at the /var/www/html
directory.
I am attempting to overwrite this data with a drupal site from a local directory on the host system.
According to the docs this is the expected behavior
Mount a host directory as a data volume
In addition to creating a volume using the -v flag you can also mount a directory from your Docker engine’s host into a container.
$ docker run -d -P –name web -v /src/webapp:/webapp training/webapp python app.py
This command mounts the host directory, /src/webapp, into the container at /webapp. If the path /webapp already exists inside the container’s image, the /src/webapp mount overlays but does not remove the pre-existing content. Once the mount is removed, the content is accessible again. This is consistent with the expected behavior of the mount command.
However I am finding that the local drupal site files do not exist on the container. My complete workflow is as follows:
docker-compose.yml drupal: container_name: empower_drupal build: ./build/drupal-local-codebase ports: - "8888:80" - "8022:22" - "443" #volumes: THIS IS ALSO NOT WORKING #- /home/sameh/empower-tap:/var/www/html $ docker-compose up -d # edit the container by snapshotting it $ docker commit empower_drupal empower_drupal1 $ docker run -d -P --name empower_drupal2 -v /home/sameh/empower-tap:/var/ww/html empower_drupal1 # snapshot the container to examine it $ docker commit 9cfeca48efd3 empower_drupal2 $ docker run -t -i empower_drupal2 /bin/bash
The empower_drupal2 container does not have the correct files from the /home/sameh/empower-tap
directory.
Advertisement
Answer
Why this did not work
Here’s what you did, with some annotations.
$ docker-compose up -d
Given your docker-compose.yml, with the volumes
section commented out, at this point you have running container, but no volumes mounted.
# edit the container by snapshotting it $ docker commit empower_drupal empower_drupal1
All you’ve really done here is made a copy of the image you had already, unless your container makes changes to itself on startup.
$ docker run -d -P --name empower_drupal2 -v /home/sameh/empower-tap:/var/ww/html empower_drupal1
Here you have run your new copy, mounted a volume. Ok, the files are available in this container now.
# snapshot the container to examine it $ docker commit 9cfeca48efd3 empower_drupal2
I’m assuming here that you wanted to commit the contents of the volume into the image. That will not work. The commit documentation is clear about this point:
The commit operation will not include any data contained in volumes mounted inside the container.
$ docker run -t -i empower_drupal2 /bin/bash
So, as you found, when you run the image generated by commit
, but without volume mounts, the files are not there.
Also, it is not clear in your docker-compose.yml example where the volumes:
section was before it was commented out. Currently it seems to be on the left margin, which would not work. It would need to be at the same level as build:
and ports:
in order to work on your drupal
service.
What to do instead
That depends on your goal.
Just copy the files from local
If you literally just want to populate the image with the files from your local system, you can do that in Dockerfile.
COPY local-dir/* /var/www/html
You mentioned that this copy can’t work because the directory is not local. Unfortunately that cannot be solved easily with something like a symlink. Your best option is to copy the directory to the local context before building. Docker does not plan to change this behavior.
Override contents for development
A common scenario is you want to use your local directory for development, so that changes are reflected right away instead of doing a rebuild. But when not doing development, you want the files baked into the image.
In that case, start by telling Dockerfile to copy the files into the image, as above. That way an image build will contain them, volume mount or no.
Then, when you are doing development, use volumes:
in docker-compose.yml, or the -v
flag to docker run, to mount a volume. A volume mount will override whatever is baked into the image, so you will be using your local files. When you’re done and the code is ready to go, just do an image build and your final files will be baked into the image for deployment.
Use a volume plus a commit
You can also do this in a slightly roundabout way by mounting the volume, copying the contents elswhere, then committing the result.
# start a container with the volume mounted somewhere docker run -d -v /home/sameh/empower-tap:/var/www/html_temp [...etc...] # copy the files elsewhere inside the container docker exec <container-name> cp -r /var/www/html_temp /var/www/html # commit the result docker commit empower_drupal empower_drupal1
Then you should have your mounted volume files in the resulting image.