So now we learn about volumes,
and specifically named volumes are useful.
Anonymous volumes, I would say,
their use is not entirely clear yet.
I'll come back to those.
But I actually now wanna dive into bind mounts first,
before we have a look at anonymous volumes again.
Because bind mounts, can help us with
a different kind of problem we might be facing.
And here is the kind of problem we might be facing.
Whenever we change anything in our source code,
be that in the server JS file, or in any HTML file here,
those changes are not reflected in the running container
unless we rebuild the image.
I mean, we do have a running application here.
And if I go back to localhost 3000,
it's actually the feedback HTML file which is loaded.
But if I add, please here, after your feedback,
and I save this file, if I reload here,
we don't see please on the page.
And it should be clear why this is happening.
I emphasized this a lot in the last module and this module,
we only copy a snapshot off this folder,
into the Docker image when it's created,
and subsequent changes to anything in that folder,
will therefore not be reflected in the image,
and therefore also not in the container.
But of course, during development, if we're using Docker,
it would be pretty important to us,
that such changes are reflected.
Because otherwise, we always have
to rebuild the entire image and restart a container,
whenever we change anything.
And of course, during development, we tend to change a lot.
So restarting everything all the time is pretty cumbersome.
That's where bind mounts can help us.
Bind mounts have some similarities with volumes,
but there is one key difference.
Where volumes are managed by Docker,
and we don't really know where
on our host machine file system they are.
For bind mounts, we do know it.
Because for bind mounts, we, as a developer,
set the path to which the container internal path
should be mapped on our host machine.
So here, we're fully aware off the path
on our localhost machine.
And since that is the case,
and containers cannot just write to volumes,
but also read from there,
of course we could put our source code
into such a bind mount.
And if we do that, we could then make sure that
the container is aware of that,
and that the source code is actually not used
from that copied in snapshot,
but instead from that bind mount.
So from that connection to some folder on our host machine.
And therefore the container would always have access
to the latest code.
And not just to the snapshot we put into our image here
when it was created at the beginning.
So bind mounts are therefore perfect,
for persistent and editable data.
And that's the difference to normal volumes.
A named volume can help us with persistent data,
but editing is not really possible, since we don't know
where it's stored on our host machine.
So how can we then add such a bind mount?
Again, it's not something we can do
from inside the Docker file.
Because it's actually specific to a container which you run,
not to the image, it doesn't affect the image,
it just affects the container.
And therefore, we have to set up a bind mount
from inside the terminal when we run our container.
So for that, first of all, I'll stop.
I'll stop my currently running container
with Docker stop feedback app.
And once this is stopped, I will rerun it,
I will create a new container in the same way,
by using Docker run.
But now I'll add more than one volume,
not just this one named volume, but a second volume,
simply by again adding dash V.
And now there is a line break,
but it's dash V and then a whitespace.
So a blank.
And then again, a volume as we added it before.
But now here's the key difference.
The folder to which I wanna map it inside of the container,
is just slash app, of course.
So just slash app, because I'm also copying
all my source code into just slash app here.
So I wanna control the entire app folder now.
But, and that's the difference.
The name which I now assign in front of the colon,
is now not app or anything like that.
Instead it is a path to the folder on my host machine,
where I have all the code, all the content,
that should go into this mapped folder.
And this must be an absolute path here, not a relative one.
You can get such a path here in Visual Studio Code
by right clicking on server JS, for example,
and choosing copy path.
Choose that, and added in front of the colon.
Yes, it's quite long, but that is what we need.
Make sure you remove the file at the end though,
it should just be the path to your project folder.
So your project folder name should be the last thing here.
In this case, at least, you can also bind a single file,
in case you just wanna share a single file with a container,
you can bind a file to a file.
But here when I wanna bind to a folder,
and therefore I wanna bind a complete folder
on my hosting machine to this app folder in the container.
That's why we're removing the file name at the end.
Because I don't just wanna share the file,
I wanna share the complete folder.
You might also wanna consider putting this into quotes,
this entire statement here.
So your absolute path, the colon, and the MapPath,
to ensure that it doesn't break in case your path
includes special characters or whitespace.
Mine doesn't, except for the slashes, which are okay.
But if your path has some blanks in it
or anything like that, simply wrap everything here,
the entire volume mapping with quotes.
Now, one important note about bind mounts
and mounting folders, which you know, into containers.
You should make sure that Docker has access to the folder
which you're sharing as a bind mount.
And you can do this by accessing the preferences of Docker,
by using that running Docker service,
this Docker process you started.
And there, make sure that under Resources file sharing,
your folder which you are sharing right now, is listed here.
It doesn't have to be the full folder,
but it should be a parent folder,
of the folder you're sharing.
If you don't have this file sharing area under Resources,
you are most likely on windows
and their you don't have this option,
you don't have this area in the settings.
If you are running Docker with help of the WSL integration,
you might remember the setup lecture,
from the first course section.
Well, if that option is missing, that's no problem,
it's missing because you won't have any problems
with file sharing anyways, with the setup you're using,
so you're fine.
Now if you should be using Docker Toolbox to run Docker,
then by default your users folder will be shared,
and attached you find a link to an article
which explains how you can share other folders as well.
So that is what you should do then,
if you are using Docker Toolbox to ensure that,
Docker is able to really write to your
localhost system machine for the given folder
you wanna use as a volume in your container.
So the attached link is for you,
if you are using Docker Toolbox.
So in my case, for example, the project I'm sharing
is in some sub folder of my users directory.
And that will be accessible by Docker,
because it's listed here, under file sharing Resources.
Now if your project is in some folder,
which is not a sub folder of one of the resources
specified here, you should make sure
that you add your project folder,
or a parent folder of it, even better,
as a shareable resource in this list
in your Docker preferences, that's important.
And if we now hit enter, this starts the container again.
And now our entire folders here,
will be mounted as a volume, into the app folder,
inside of the container.
Nonetheless, you'll notice if you reload, that it crashes.
And if we inspect our running
and shutdown containers thereafter,
we see this container is nowhere to be found.
And we don't find it in the closed containers,
in the stopped containers,
because we remove all containers which are shut down.
But this of course also means that,
it seems to shut down immediately.
So something seems to be very wrong here.
And to find out what's wrong, I'll restart it again.
But now without dash, dash RM,
to not automatically remove it
when it shuts down.
And thereafter we see it here, under stopped containers.
And we can now use Docker logs, to look into our container,
to see the error that was thrown.
And we see that the problem is,
that it fails to find the module Express.
And that simply means that our node code
doesn't even start executing,
because an important dependency is missing.
Now up to this point, it always worked, of course.
And after all, we are installing all dependencies
with the npm install instruction in the Docker file.
So why is it missing now?
Well, that has something to do with
our newly added bind mount.
With this bind mount that binds our entire project folder
to the app folder.
And we'll see what's wrong and how to solve the problem,
in the next lecture.