Mounting my container to my local application codebase breaks node_module binaries PATH

FROM docker-ro.visable.com/wlw_node:14.14.0-alpine
WORKDIR /app
ENV PORT 3000
ENV NUXT_HOST=0.0.0.0
ENV NUXT_PUBLIC_PATH=/company_profile_frontend/_nuxt/
COPY package.json yarn.lock /app/
COPY . /app
RUN yarn install
# Expose port
EXPOSE $PORT
CMD [ "nuxt" ]

When I run this with

docker run -d -p 3000:3000 company-profile-frontend-dev

things work fine - nuxt is found and executed. (its framework built on top of Node/Vue)

the issue with the above is my host codebase and my container codebase isn’t in sync which is as you can imagine kind of problematic.

Volumes to the rescue!

Run from the directory of the app:

docker run --name cpp-dev -d -p 3000:3000 -v $PWD:/app company-profile-frontend-dev

Unfortunately this doesn’t work, nuxt is not found. (it works when node_modules are installed on my localhost machine)

That could actualy be the solution, as volumes copy existing content from the container target folder back into the volume when they are used the first time.

Though you are using a bind-mount, which simply mounts a host folder on top of the container target folder making it original content inaccessible - you only get the content of the mounted host folder. bound-minds are not listed in docker volume ls.

You can create a volume baked by a bind-mount like this:
docker volume create --opt type=none --opt o=bind --opt device=/host/path/ volume_name

Once created, you will see it listed in docker volume ls.

Then use it as docker run --name cpp-dev -d -p 3000:3000 -v volume_name:/app company-profile-frontend-dev

Isn’t there a way to put all dependenicies outside the /app folder or just mount a sub folder that actualy requires your local code changes?

thank you for the answer, I’m afraid I’m little more confused now…

First of all, my goal is to be able to make changes to files on my local system and have them being reflected to the container file system (and vice versa?) (I saw some folks use rsync for that btw)

Since the above needs to be automated, (I don’t want to have to run multiple CLi commands), would a docker-compose be a more suitable solution?

Is there a way to create a volume which is also bind-mounted with 1 command? This is the docs I followed: Use volumes | Docker Documentation and I thought one command is sufficient.

Sure it is. If only you would have posted your stuff as compose.yml, then I would have added the compose configuration. This would haved saved us both time.

Just out of curriousity what makes you think that it’s more than a single command?

By “2” commands, I meant is it possible to use the -v flag with docker run and create the volume together with the docker run?

Last but not least, could you elaborate on the flags you’re using below and how they differ from the simple -v <localhost path>:<container path> ?

docker volume create --opt type=none --opt o=bind --opt device=/host/path/ volume_name

As we both would need to look into the documentation for that, I’ll leave this one to you. Haven’t used it that way myself. My volumes are all declare in compose files. I would urge you to give docker compose a try, it will make your life easier in the future.

The left hand side determin whether it is a bind-mount or a volume. If it’s a path, a bind-mount will be used, if it’s a volume name, the named volume will be used. If the volume doesn’t exist, it will be created, though I have no idea if it can be parameterized to be actualy a bind-mount baked volume…

This command creates a volume using the local driver (which is the default driver). local means localy managed on this node, it says nothing wether the data source is a local filesystem or a remove nfs/cifs share. The local driver supports whatever mount is able to mount…

Since the local driver is the default driver, that part is skipped. --opt type=none --opt o=bind declare that you want to create a bind baked volume. --opt device=/host/path is the host path you want use for the bind (this should be the path you had on the left hand side of the volume declaration before) and volume_name is simply the name of the created volume.

1 Like

Thank you. I still didn’t understand what my shorthand command is missing and why it’s not working properly.

Welcome!

Could you rephrase that for me?