Mounting a host directory with Docker Compose in Windows - docker

I'm using Docker for Windows on WSL2. When I do this on a Dockerfile, the contents of my directory in the host are copied correctly to the new image after building:
FROM node:latest
WORKDIR /app
COPY . /app
However, this docker compose YAML doesn't mount the same directory in the same location:
version: "2.0"
services:
node:
image: node
user: node
environment:
- NODE_ENV=production
volumes:
- ./:/home/node/app
tty: true
After accessing the container, I'm not able to see the contents on my host directory in it. I've also tried with the full host path, but it didn't work.
When I run docker inspect on my container, I see this, which contains the correct information:
"Mounts": [
{
"Type": "bind",
"Source": "/mnt/c/Users/my-user/my-dir",
"Destination": "/home/node/app",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
}
],
What am I missing?

Related

Named volume with local bind defined in docker compose not working but working when externally defined

I want to use a named volume inside my docker compose file which binds to a user defined path in the host. It seems like it should be possible since I have seen multiple examples online one of them being How can I mount an absolute host path as a named volume in docker-compose?.
So, I wanted to do the same. Please bear in mind that this is just an example and I have a use case where I want to use named volumes for DRYness.
Note: I am using Docker for Windows with WSL2
version: '3'
services:
example:
image: caddy
restart: unless-stopped
volumes:
- caddy_data:/data
- ./Caddyfile:/etc/caddy/Caddyfile
volumes:
caddy_data:
name: caddy_data
driver_opts:
o: bind
device: D:\Some\path_in\my\host
type: none
# volumes:
# caddy_data:
# external: true
# name: caddyvol
This does not work and everytime I do docker compose up -d I get the error:
[+] Running 1/2
- Volume "caddy_data" Created 0.0s
- Container project-example-1 Creating 0.9s
Error response from daemon: failed to mount local volume: mount D:\Some\path_in\my\host:/var/lib/docker/volumes/caddy_data/_data, flags: 0x1000: no such file or director
But if I create the volume first using
docker volume create --opt o=bind --opt device=D:\Some\path_in\my\host --opt type=none caddyvol
and then use the above in my docker compose file (see the above file's commented section), it works perfectly.
I have even tried to see the difference between the volumes created and have found none
docker volume inspect caddy_data
[
{
"CreatedAt": "2021-12-12T18:19:20Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "ngrok-compose",
"com.docker.compose.version": "2.2.1",
"com.docker.compose.volume": "caddy_data"
},
"Mountpoint": "/var/lib/docker/volumes/caddy_data/_data",
"Name": "caddy_data",
"Options": {
"device": "D:\\Some\\path_in\\my\\host",
"o": "bind",
"type": "none"
},
"Scope": "local"
}
]
docker volume inspect caddyvol
[
{
"CreatedAt": "2021-12-12T18:13:17Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/caddyvol/_data",
"Name": "caddyvol",
"Options": {
"device": "D:\\Some\\path_in\\my\\host",
"o": "bind",
"type": "none"
},
"Scope": "local"
}
]
Any ideas what's going wrong in here?
Finally managed to figure it out thanks to someone pointing out half of my mistake. While defining the volume in the compose file, the device should be in linux path format without the : after the drive name. Also, the version number should be fully defined. So, in the example case, it should be
version: '3.8'
services:
example:
image: caddy
restart: unless-stopped
volumes:
- caddy_data:/data
- ./Caddyfile:/etc/caddy/Caddyfile
volumes:
caddy_data:
name: caddy_data
driver_opts:
o: bind
device: d/Some/path_in/my/host
type: none
But this still did not work. And it seemed to not work only in Windows Docker Desktop. So, I went into \\wsl.localhost\docker-desktop-data\version-pack-data\community\docker\volumes and checked the difference between the manually created volume and the volume generated from the compose file.
The only difference was in the MountDevice key in the opts.json file for each. The manually created file had /run/desktop/mnt/host/ appended to the path provided. So, I updated my compose file to
version: '3.8'
services:
example:
image: caddy
restart: unless-stopped
volumes:
- caddy_data:/data
- ./Caddyfile:/etc/caddy/Caddyfile
volumes:
caddy_data:
name: caddy_data
driver_opts:
o: bind
device: /run/desktop/mnt/host/d/Some/path_in/my/host
type: none
And this worked!

Xdebug 3 doesn't connect in docker

I used this docker-compose file with the Xdebug options that worked for me in a local Xdebug installation, but doesn't work in Docker.
version: '3'
services:
app:
container_name: php7.3-xdebug
image: 'php7.3-xdebug-i'
ports:
- '9090:80'
build:
context: ./
dockerfile: ./dockerfile
volumes:
- ./:/var/www/html
environment:
XDEBUG_CONFIG: zend_extension=xdebug.so xdebug.mode=debug xdebug.start_with_request=yes xdebug.client_host=host.docker.internal
This is the Dockerfile:
FROM php:7.3.28-apache-buster
RUN pecl install xdebug-3.0.4 \
&& docker-php-ext-enable xdebug
COPY . /var/www/html
WORKDIR /usr/src/myapp
and this launch.json in VSCode:
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceFolder}",
},
},
{
"name": "Launch currently open script",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9003
}
]
}
I tried a lot of configs but there is no way to make it work.
XDEBUG_CONFIG: zend_extension=xdebug.so xdebug.mode=debug
xdebug.start_with_request=yes xdebug.client_host=host.docker.internal
This line is incorrect:
You can't load extensions through an Xdebug specific environment variable (but the docker-php-ext-enable xdebug line in your Dockerfile should have taken care of this already).
If you want to set settings through XDEBUG_CONFIG, then you should not prefix them with xdebug., which is explained in the documentation.
The documentation also says that only a select set of settings can be set through XDEBUG_CONFIG, and start_with_request is not one of these. It needs to be set in a PHP ini file.
To set Xdebug's mode, you need to use the XDEBUG_MODE environment variable instead, as is explained in the documentation again.

Docker volume clears folder in container on windows 10

I've created a simple docker with a nodejs server.
FROM node:12.16.1-alpine
WORKDIR /usr/src
COPY ./app/package.json .
RUN yarn
COPY ./app ./app
This works great and the service is running.
Now I'm trying to run the docker with a volume for local development using docker compose:
version: "3.4"
services:
web:
image: my-node-app
volumes:
- ./app:/usr/src/app
ports:
- "8080:8080"
command: ["yarn", "start"]
build:
context: .
dockerfile: ./app/Dockerfile
This is my folder structure in the host:
The service works without the volume. When I add the volume, the /usr/src/app is empty (even though it is full as shown in the folder structure).
Inspecting the docker container I get the following mount config:
"Mounts": [
{
"Type": "bind",
"Source": "/d/development/dockerNCo/app",
"Destination": "/usr/src/app",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
}
],
But still, browsing to the folder via shell of vscode show it as empty.
In addition, the command: docker volume ls shows an empty list.
I'm running docker 18.09.3 on windows 10.
Is there anything wrong with the configuration? How is it supposed to work?
Adding the volume to your service will remove all the files /usr/src/app and mount the content of ./app from your host machine. This also means that all files generated by running yarn in the docker image will be lost because they exist only in the docker image. This is the expected behaviour of adding volume in docker and it is not a bug.
volumes:
- ./app:/usr/src/app
Usually and for none development Envs you don't need the volume at all here.
If you would like to see the files on your host, you need to run yarn command from docker-compose (you can use an entry point)

Docker container can't mount folder

I am working on an application. Using NodeJS for language and docker docker-compose for deployment.
I have an endpoint for uploading files. When i upload a file application keeps it at the "files" folder (files folder is at the root of the project). When container restarts i dont want to loose files, so i created a volume named "myfiles" and mounted it to "/files" path.
But when i check the myfiles volume path i dont see any of the created files by api. And if i restart the container uploaded files disappears.
Here is my docker-compose.yaml file for api
version: '3.1'
services:
api:
image: api-image
restart: always
volumes:
- myfiles:/files
volumes:
myfiles:
After docker-compose up -d i upload some files and see them in container by calling
docker exec -it container_name ls
files node_modules package.json
index.js package-lock.json src
docker exec -it container_name ls files
d5a3455a39d8185153308332ca050ad8.png
Files created succesfully.
I checked if container mounts correctly by
docker inspect container_name and result:
"Mounts": [
{
"Type": "bind",
"Source": "/var/lib/docker/volumes/myfiles/_data",
"Destination": "/files",
"Mode": "rw",
"RW": true,
"Propagation": "rslave"
}
]
You are creating volume, you are not using folder. Try to use folder myfiles from current directory:
version: '3.1'
services:
api:
image: api-image
restart: always
volumes:
- ./myfiles:/files

Mounting volume in Azure-Container-Service not working for traefik.toml and /var/run/docker.sock

Building an CI/CD pipeline from VSTS to Azure-container-service I've ran into an issue mounting the traefik.toml and the docker.sock file.
The deployment uses an SSH tunnel to create a folder /Deploy/ and copy the docker-compose.yml and traefik.toml. The files are there, the containers are spun up. Yet not handled by traefik, because it does not 'see' the containers.
The traefik tutorial shows we can mount the like so in a docker-compose.yml:
version: '2'
services:
proxy:
build:
context: .
dockerfile: /Traefik/dockerfile
restart: always
command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG
networks:
- internal
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /dev/null:/traefik.toml
This runs perfectly fine on my windows 10 machine, running docker 17.09.0-ce
But when deployed to Azure-Container-Service I receive the following error:
ERROR: Named volume "\var\run\docker.sock:/var/run/docker.sock:rw" is used in service "proxy" but no declaration was found in the volumes section.
https://github.com/docker/compose/issues/3073 opts for an extra dot (.) to signal it's a mapping to the host volume. Tried it, no error but it does not actually mount.
"Mounts": [
{
"Type": "bind",
"Source": "/home/dutchitworks/deploy/.\\var\\run\\docker.sock",
"Destination": "/var/run/docker.sock",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/home/dutchitworks/deploy/.\\dev\\null",
"Destination": "/traefik.toml",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
}
],
it adds the /home/dutchitworks/deploy/. from somewhere...
Any ideas how the get the traefik.toml mapped correctly would be welcome...

Resources