Reputation: 16287
Based on:
https://shekhargulati.com/2019/01/18/dockerizing-a-vue-js-application/
I am trying to run a container that supports hot reload. According to above guide that should be possible with running the docker run command:
docker run -it -p 8081:8080 -v ${PWD}:/app/ -v /app/node_modules --name CONTAINER_NAME FRONTEND_IMAGE
But I don't understand this part: -v ${PWD}:/app/ -v /app/node_modules
. Looking at the first part:
-v ${PWD}:/app/
According to the documentation:
https://docs.docker.com/storage/bind-mounts/
the first parameter to -v
is the name of the volume. Why would you select the name ${PWD}
as the name? In my case that ends up being: /home/user/code/sample001
In the second case:
-v /app/node_modules
the volume does not even have a name. Comparing that with example from the docker docs:
$ docker run -d \
--name devtest \
-v myvol2:/app \
nginx:latest
I don't see how -v /app/node_modules
even makes sense.
If I then do:
$ docker inspect CONTAINER_NAME
...
"HostConfig": {
"Binds": [
"/home/user/code/sample001:/app/"
],
...
"Mounts": [
{
"Type": "bind",
"Source": "/home/user/code/sample001",
"Destination": "/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "volume",
"Name": "83cbd979484473e3a5a258b8dbad052bc8927e207aa2dc4afa73be72113d3102",
"Source": "/var/lib/docker/volumes/83cbd979484473e3a5a258b8dbad052bc8927e207aa2dc4afa73be72113d3102/_data",
"Destination": "/app/node_modules",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
-v ${PWD}:/app/
actually creates a bind and not a volume.
What am I missing?
Upvotes: 0
Views: 116
Reputation: 4721
There are three types of volumes: host, anonymous and named. see Different Types of Volumes
The /app/node_modules
is an anonymous volume and it's handled directly by docker.
As mentioned in the article:
the second -v flag ensures that host node_modules does not override the node_modules of the container. To ensure that, we create a data volume for /usr/src/app/node_modules . If you will run the docker run command without the second -v flag then you will get error vue-cli-service: not found.
The built image contains the node_modules
in app/node_modules
. If you don't specify the anonymous volume during the container initialization the whole app
directory will be mounted inside the container overwriting
the existing node_modules
directory. If you do specify it, docker will mount the volume on host in /var/lib/docker/volumes
. To find out where it's located run:
docker inspect -f '{{ .Mounts }}' containerid
The command:
docker run -it -v ${PWD}:/usr/src/app -v /usr/src/app/node_modules -p 5000:5000 myapp
is meant to be executed in development to mount the sources into the container because they are not copied during the build of the dev image.
All this is done to have the sources on the host and keep the modules in the container. One of the reasons is that dependencies may depend on the operating system so it is important to develop with the container version of the node modules.
Once everything is ready to go into production the image is built from a different Dockerfile
which copies the sources and install the dependencies. In this case there are no volumes mounted:
docker build -f Dockerfile-prod -t myapp-prod .
Upvotes: 2