With Docker, we actually
have multiple external data storage mechanisms,
if we wanna call them like this, two to be precise.
And that would be volumes and bind mounts.
Now, we'll worry about bind mounts later.
For the moment we'll focus on volumes.
And it looks like they don't fully work as we want to.
Because we actually also have two types of volumes,
and both have their own special purposes and use cases.
Currently we're using anonymous volumes.
Or to be precise with this instruction
in the Docker file,
we add an anonymous volume to this image and data for it
to the containers running based on that image.
Now, we can also assign named volumes,
and that's not something we're doing up to this point.
Now in both cases,
no matter if it's anonymous or named,
however that works, we'll see it soon.
In both cases, Docker sets up some folder
and path on your host machine.
You don't know where.
After all, here we only specified a path
inside of the container,
no path on our host machine.
So we don't know where the folder is
in which this is mirrored.
It's somewhere managed by Docker,
but we don't know where.
And the only way for us to get access
to these volumes is with help of the Docker volume command.
And I can show this to you.
If we go back here to the terminal,
we can run Docker volume --help to see our options.
And here it's Docker volume ls
to list all volumes Docker is currently managing.
And we see one volume here.
Let me show it to you again.
We see one volume here with a very strange cryptic name.
This name is this cryptic
because it's an automatically generated name.
Because it's an anonymous volume,
we didn't assign any name to it.
Hence Docker automatically assigned one.
Now here's the gotcha.
If we stop our feedback app container,
and therefore for we shut down this application,
if we inspect our volumes again
this anonymous volume is gone.
It doesn't exist anymore.
Now as I said, it's managed by Docker.
And because it's anonymous,
it actually only exists as long as our container exists.
And that doesn't help us at all with the problem I outlined,
which was that our data disappears
if we shut down a container.
Now I will come back
to where anonymous volumes can be helpful,
but let's have a look at named volumes, then.
Maybe these'll help us.
Because they share one key concept
with anonymous volumes and actually all the bind mounts,
as you will learn later,
which will be helpful to us.
A defined path in a container
is mapped to some created volume.
So to some created path on the host machine.
So for example here,
this app feedback path
in a container is mapped to some folder on the host machine.
We just don't know which path
because it's managed by Docker.
I can tell you it's hidden somewhere on your computer,
and it's not meant to be accessed by you.
So it's hard to find out where exactly it is,
but also we shouldn't access
and work in that folder anyways.
So that's why this is fine.
But that theoretically is a promising concept
if only the volume wouldn't be deleted
when a container shuts down.
If that would be the case
and the folder would survive on our local machine,
then everything would be good.
And here's the good news, finally.
With named volumes, that will be the case.
With named volumes,
volumes will survive container's shutdown.
The folders on your hard drive will survive.
And therefore, if you start new containers thereafter,
the volumes will be back, the folder will be back,
and all the data stored in that folder
will still be available.
So named volumes are great for data
which should be persistent,
and that's important,
which you don't need to edit or view directly,
because you don't really have access
to that folder on your host machine.
As I just said, it's hidden somewhere managed by Docker,
and it's hard to find out where it is.
And it's not meant to be edited by you.
I'll come back to an option which you can edit later.
So named volumes would be interesting here.
I'll come back to anonymous volumes
and where they can help us as well.
But for the moment we need named volumes.
And we can't create named volumes inside of a Docker file,
hence we can remove this instruction actually.
Instead we have to create a named volume
when we run a container.
So therefore first of all,
I'll rebuild my image here
since I removed that volume's instruction.
So first of all, I'll remove it.
And then I will repeat that build command
to build that image with that tag.
And once it was rebuilt,
I will now once again restart my container
based on that image with the Docker run command,
but not like this.
Instead now I add another flag,
another option to this command.
And that's the -V option, which stands for volume,
which allows me to add a volume to this container.
But unlike in the Docker file,
not just an anonymous volume but actually a named volume.
And here's how that works.
We still specify the path inside
of the container file system which we wanna save.
And in our case, that's app/feedback.
This hasn't changed.
But in front of this path,
we now provide any name of our choice.
For example, feedback.
We then add a colon to separate our name from that path.
And this is a syntax Docker will understand,
and it will now store app feedback in a managed volume.
So it will create a folder on our hosting machine
and connect it to this folder inside of the container,
but it will store this volume under a name chosen by us.
And the key difference to anonymous volumes
is that named volumes will not be deleted
by Docker when the container shuts down.
Anonymous volumes are deleted because they are recreated
whenever a container is created.
And therefore, keeping them around
after a container was removed makes no sense.
Anonymous volumes are closely attached
to one specific container.
Named volumes are not attached to a container.
And therefore here, if I now run this,
I can go back to local host 3000,
add another feedback or another message here, save this.
And of course, visit feedback/awesome.txt.
And see that.
But now, finally, I promise if we stopped this
with Docker stop feedback app,
and this will remove the container
because of the -- rm flag,
our volume will still be there.
And hence, if we restart a new container
with the same volume, our data will still be there.
So let's first check for the volume with Docker volume ls.
And you see that's the name we chose,
and it's still there even though the container was stopped.
That's different compared to before.
And if we now restart the container by using Docker run.
So I'm not restarting the same container.
I'm creating a new container.
But if I do that, and that's important,
the same -V option with the same volume name,
so the same name as before,
now, this restarts.
And now if I reload here,
you see finally the data is still there.
So finally we managed to persist data
with the help of volumes,
to be precise, with the help of named volumes.