Fail to setup read-only bind mount and anonymous volume

I am new to docker and learning how to setup bind mount and volume. I am using Windows cmd to run a container. Here is my Dockerfile:

FROM node
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 80
# VOLUME ["/app/node_modules"]
CMD ["node", "server.js"]

and here is my run cmd:
docker run -d --rm -p 3000:80 --name feedback-app -v feedback-volume:/app/feedback -v %cd%:/app:ro -v /app/node_modules feedback-image

I want to set /app to be read-only and set /app/node_modules to be anonymous volume so the read-only properties of node_modules can be override. But I get this error:

Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/var/lib/docker/volumes/0dcbca99e6093d9171800849fb5106bea033758ce7e49925bb680e324d5a8c63/_data" to rootfs at "/app/node_modules": mkdir /var/lib/docker/overlay2/fac5c7b72a379db479ea573fe75e3f5bd45fa8a6915fa6e4433dbc5e0a2a1402/merged/app/node_modules: read-only file system: unknown.  

I think I have the exact same way with the tutorial video. Don’t know which part is going wrong.

This volume argument is incomplete. It lacks either a host path for a bind or a volume name.

I think that’s anonymous volume.

Yes, you are right. It indeed creates an anonymous volume on the host.

I have no idea what causes this error message ~, but personally I would remove all volume arguments and re-add them one by one to isolate which of those volume arguments causes the problem.~

Update: I should not respond to topics, when I am not still awake… Of course it’s the argument for the anonymous volume.

I think the problem is that you want to mount a folder over a read-only filesystem. When you bind mount a folder into the container and you mount another folder under mount point of the bind mount, an empty folder is created in the bind mounted folder. Which can’t be created when the parent is read-only. You could create the empty folder on the host and try again. Nothing will be created in that folder, it is just required for Docker to mount a volume in a bind mounted folder.

The reason is probably that when you bind mount a folder on Linux even without Docker, just using the mount command, the target folder always has to exist. Docker can create it for you depending on whether you use the short or long syntax, but can’t on a read-only filesystem.

2 Likes

Well spotted! I missed that the parent folder for the target folder is a read-only bind.

You are right! That solves the problem. Thanks!