Mounting local folder to windows container using docker compose - docker

There are lots of post on this topic but either they are discussing about docker run or linux or discussing about earlier version of docker/ docker compose. I am simply trying to share a config file that resides locally, with my container. The following is my docker compose
version: "3.8"
services:
TestService:
image: testservicelogmon
build:
context: .
dockerfile: Dockerfile
volumes:
- C:\ProgramData\Solution Name\Project Name:C:\ProgramData\Solution Name\Project Name:RW
Note: "Solution Name" and "Project Name" have space between them, and my config file resides in Project name folder.
The images gets created successfully but I always have "Mounts": [] and "Volumes": null.
I went through the documentation and some posts at SO but couldn't find anything that would solve this problem for me. Below are couple of links I referred to. Any help on this would be appreciated. Thanks !
Update: It's just not with this folder, it seems like I am not able to mount any folder, whereas if I do a docker runlike below it works perfectly fine.
docker run -it -v 'C:\ProgramData\Solution Name\Project Name:C:\ProgramData\C:\ProgramData\Solution Name\Project Name:RW' testservicelogmon:latest powershell
docker named volume with targeting windows local folder
volume binding using docker compose on windows

The code seems to work fine. I was making a stupid mistake of running the docker-compose build command followed by docker run. This way everything was working fine but the mounts would always show empty. All I had to do was run docker-compose build followed by docker-compose up and the mounts were populated as expected.

Related

Mount files in read-only volume (where source is in .dockerignore)

My app depends on secrets, which I have stored in the folder .credentials (e.g. .credentials/.env, .credentials/.google_api.json, etc...) I don't want these files built into the docker image, however they need to be visible to the docker container.
My solution is:
Add .credentials to my .dockerignore
Mount the credentials folder in read-only mode with a volume:
# docker-compose.yaml
version: '3'
services:
app:
build: .
volumes:
- ./.credentials:/app/.credentials:ro
This is not working (I do not see any credentials inside the docker container). I'm wondering if the .dockerignore is causing the volume to break, or if I've done something else wrong?
Am I going about this the wrong way? e.g. I could just pass the .env file with docker run IMAGE_NAME --env-file .env
Edit:
My issue was to do with how I was running the image. I was doing docker-compose build and then docker run IMAGE_NAME, assuming that the volumes were build into the image. However this seems not to be the case.
Instead the above code works when I do docker-compose run app(where app is the service name) after building.
From the comments, the issue here is in looking at the docker-compose.yml file for your container definition while starting the container with docker run. The docker run command does not use the compose file, so no volumes were defined on the resulting container.
The build process itself creates an image where you do not specify the source of volumes. Only the Dockerfile and your build context is used as an input to the build. The rest of the compose file are all run time settings that apply to containers. Many projects do not even use the compose file for building the image, so all settings in the compose file for those projects are a way to define the default settings for containers being created.
The solution is to using docker-compose up -d to test your docker-compose.yml.

Mounted directory empty with docker-compose and custom Dockerfile

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.
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)..
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.

Docker versus Docker-compose with dockerignore

Are docker and docker-compose supposed to differ in their handling of .dockerignore?
I've got a Docker container which builds fine when I build it directly, e.g. via docker build -t mycontainer ./mycontainer, but it fails when I build it via docker-compose up. Relevant portion of the docker-compose.yml is
version: '3'
services:
mycontainer:
build: ./mycontainer
ports:
- "1234:1234"
expose:
- "1234"
By using docker run --rm -it --entrypoint=/bin/bash 240e1a06c8f5, where 240e1a06c8f5 is the last image before the build failure, I found that one of the files, ./mycontainer/mymodel/labels.rdata, wasn't being copied over by docker-compose up, but is copied by docker build. It's also close to a pattern in the .dockerignore, */*.RData.
Is this a difference between case-sensitivity in .dockerignore between docker-compose and docker build? Is it a difference in path handling? Is this a known bug? (or intended?)
Versions on MacOs:
$ docker --version
Docker version 18.09.1, build 4c52b90
$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01
I just tried using a case-insensitive .dockerignore entry on Windows and it did actually ignore the file, so it looks like your */*.RData will actually ignore your ./mycontainer/mymodel/labels.rdata file.
Try changing the extension of the file or changing the ignore entry. I'd change the filename, since that seems like the one-off here.
EDIT: This does sound like a bug. I'd file one on their Github Issues page since I don't see one there already

How to create data volume in docker?

I am having some gitcode (around 10gb) kept in a folder "src" in my home directory. I have read somewhere that we can mount this code as a data volume in docker.
I am a newbie to docker. I only have an idea of using "docker volume create" command, but totally unsure about how to use it.
Could someone help me in achieving this.
Bishal's answer has instructions how to use mapping with Docker compose. When using plain docker, use command
docker run -v <absolute path to src folder on host>:<absolute path on container> some-image
# Real example:
docker run -v ~/src:/src some-image
Docker allows for easy volume mapping. This can be configured in your docker-compose.yaml file.
Volume mapping allows you to share a directory in your host machine to your docker-container.
version: '2'
services:
web:
build: .
volumes:
- .:/code
In the above snippet, the files in the current directory of host machine will be mapped to /code of the docker container.
This article has detailed explanation.

Host Volumes Not getting mounted on 'Docker-compose up'

I'm using docker-machine and docker-compose to develop a Django app with React frontend. The volumes don't get mounted on Debian environment but works properly on OSX and Windows, I've been struggling with this issue for days, I created a light version of my project that still replicate the issue you can find it in https://github.com/firetix/docker_bug.
my docker-compose.yml:
django:
build: django
volumes:
- ./django/:/home/docker/django/
My Dockerfile is as follow
FROM python:2.7
RUN mkdir -p /home/docker/django/
ADD . /home/docker/django/
WORKDIR /home/docker/django/
CMD ["./command.sh"]
When I run docker-compose build everything works properly. But when I run docker-compose up I get
[8] System error: exec: "./command.sh": stat ./command.sh: no such file or directory
I found this question on stackoverflow
How to mount local volumes in docker machine followed the proposed workarounds with no success.
I'm I doing something wrong? Why does this work on osx and windows but not on Debian environment? Is there any workaround that works on a Debian environment? Both Osx and Debian have /Users/ folders as a shared folder when I check VirtualBox GUI.
This shouldn't work for you on OSX, yet alone Debian. Here's why:
When you add ./command.sh to the volume /home/docker/django/django/ the image builds fine, with the file in the correct directory. But when you up the container, you are mounting your local directory "on top of" the one you created in the image. So, there is no longer anything there...
I recommend adding command.sh to a different location, e.g., /opt/django/ or something, and changing your docker command to ./opt/command.sh.
Or more simply, something like this, here's the full code:
# Dockerfile
FROM python:2.7
RUN mkdir -p /home/docker/django/
WORKDIR /home/docker/django/
# docker-compose.yml
django:
build: django
command: ./command.sh
volumes:
- ./django/:/home/docker/django/
I believe this should work. there were some problems with docker-compose versions using relative paths.
django:
build: django
volumes:
- ${PWD}/django:/home/docker/django

Resources