0

I am very (read very) new to Docker so experimenting. I have created a very basic Dockerfile to pull in 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

My docker-compose.yml file looks like:

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

When I run docker-compose up, the ./site directory is created but the contents are empty. I've put this in docker-compose as I plan on on including other things like nginx, mysql, php etc

The command:

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

Results in the same behaviour.

I know the install is successful as I modified my dockerfile with the follwing two lines appended to it:

WORKDIR /var/www/site
RUN ls -la

Which gives me the correct listing.

Clearly misunderstanding something here. Any help appreciated.

1 Answer 1

1

EDIT: So, I was able to get this to work... although, it slightly more difficult than just specifying a path..

You can accomplish this by specifying a volume in docker-compose.yml.. The path to the directory (on the host) is labeled as device in the compose file.. It appears that the root of the path has to be an actual volume (possibly a share would work) but the 'destination' of the path can be a directory on the specified volume..

I created a new volume called docker on my machine but I suppose you could do this with your existing disk/volume..

I am on a Mac and this docker-compose.yml file worked for me:

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

The container specified exists in my DockerHub.. this is the source code for it, just in case you are worried about anything malicious. I created it like two weeks ago to help someone else on StackOverflow.


Shows files from the container on my machine (the host)..

enter image description here


You can read more about Docker Volume configs here if you would like.


ORIGINAL ANSWER:

It looks like you are trying to share the build directory with your host machine.. After some testing, it appears Docker will overwrite the specified path on the container with the contents of the path on the host.

If you run docker logs my_laravel you should see an error about missing files at /var/www/site.. So, even though the build is successful - once Docker mounts the directory from your machine (./site) onto the container (/var/www/site) it overwrites the path within the container (/var/www/site) with the contents of the path on your host (./site) - which is empty.

To test and make sure the contents of /var/www/site are in fact being overwritten, you can run docker exec -it /bin/bash (you may need to replace /bin/bash with /bash).. This will give you command line access inside of the container. From there you can do ls -a /var/www/site..

Furthermore, you can also pre-stage ./site to have a random test file in it (test.txt or whatever), then docker-compose up -d, then run the same commands from the step above docker exec -it ... and see if the staged test.txt file is now inside the container - this gives you definitive evidence that when you run volumes, the data on your host overwrites data in the container.

With that being said, doing something like this and sharing a log directory will work... the volume path specified on the container is still overwritten, the difference is the container is writing to that path.. it doesn't rely on it for config files/app files.

Hope this helps.

Sign up to request clarification or add additional context in comments.

3 Comments

You are quite right. Any volumes I define will be pulled into the container and thus overwrite anything in there. I'm looking at a different way using CMD to accomplish what I want i.e. - populating the bound directory when the container is first invoked.
@Zakalwe I figured out how to accomplish this - I have updated my answer with an explanation on how I did it.
This is great thank you! Just need to tidy up some Laravel-specific permissions but this did the trick, Thanks for looking into this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.