So let's start working on the MongoDB
container and let's make sure that data persists there,
and that we limit the access.
Just to clarify what the problem is.
At the moment, if I Docker stop MongoDB
and keep in mind that we currently have one goal.
If I stop MongoDB and I then rerun it in the same way
as before it works and our application will be able
to talk to it, but the goal is gone.
It's no longer there.
And that happens because when we stop MongoDB,
the container is removed, and when it's removed,
all the data stored in the container is lost.
And the data stored in the database, in the MongoDB database
is stored in that container of course.
So therefore here, we need to ensure that we detach
that data, which in the end is still written
to the hard drive.
Databases also store data on a hard drive somewhere
that that data survives container tear down and removal.
And of course we learned
how we can ensure that data survives.
We can add a volume.
We do this with the dash V flag,
and then we just need to know which path the MongoDB
container uses internally for storing that database data.
And of course, since this isn't our image,
we don't know which path gets used internally,
but we can of course look into the documentation
of this Mongo container.
And there we learn a lot about using this image
and how we can start it and so on,
and we also learn that we can indeed use a volume there.
And what we can see here is that internally,
it seems to be this slash data slash DB folder
in which MongoDB stores the database data,
the database files inside of the container.
Now here in this example, this gets mapped to a bind Mount,
so to a local host machine folder which we know.
This could be useful for being able to inspect
that database conveniently, but we actually don't need
to do that just to persist data.
Instead, all we need to do for that is
as you'll learned in the Volumes and Data Storage section,
a named volume.
So we could name it data and bind this to data/db.
Now that's not a bind mount because we don't have a full
path to a local host machine folder.
Instead we just assign a name and then we map this
to a path instead of the container.
And as you learned, Docker will then create this volume,
if it doesn't exist already and store any data written
inside of the container in that volume on the host machine,
we just don't know where that is on the host machine.
And if it does exist already, Docker will load the data
that's already in that folder on the host machine,
into that folder in the container.
And this then ensures that our data is never lost.
So for now hit enter, I should first of all
stop my MongoDB container of course,
and then try this again and hit enter
to start at MongoDB container again now with this volume.
And that means that now one last time the data is lost,
but if a learn Docker this is saved and persists,
and now it even survives if I stop Mongo again.
If I stop this container again, and I then rerun it,
hence creating a new container, now, if I reload,
you see the data is still there because of that volume.
So that's our data surviving in the MongoDB container,
which is one key requirement we had here.
Now another requirement was security
and preventing access to our database.
And for that the MongoDB image supports
two environment variables, MongoINITDB root username,
and MongoINITDB root password.
And when we use these environment variables,
then the database insert at the MongoDB container will
be created such that this username
and password is required to access it.
And that can of course be convenient because that can ensure
that we need to specify that username and password
in our containers trying to access our database,
which simply adds an extra layer of security.
If we scroll up a bit further,
we see a more detailed usage guide.
So in the end, what we can do here is we can stop
our MongoDB container again, and then run it again
but now by also adding an environment variable,
and the first one which I want to add is MongoINITDB
root username and set it to a value of max, for example,
in my case, and add a second environment variable,
which is this MongoINITDB root password environment
variable, which I will also set to secret here.
Now that's of course not a secure username or password,
but it is good enough here for development.
With that if I hit enter, this now starts up.
This container is now up and running.
And if we now reload here, you see fetching data fails.
And that fails because the node application,
which talks to MongoDB,
connected without that password and user
and now that database is protected though.
So now we need to ensure that in our app JS file
of our node backend,
indeed we do utilize that password and username
we just used for starting the database.
So max in my case and secret as a password.
And for that we can manipulate this connection string a bit
because this Mongo DB connection string
has a special format which is understood
by MongoDB in the end,
The format is such that we can have a username and password,
which we add in front of the actual host address by having
username then a colon, then password and then I add symbol.
This is optional, but now we need it,
since we now do have a username and a password.
So in my case would be max:secret@mongodb.
And with this now, if we rebuild the node image
and then restart the container,
we should be able to connect again.
So let's give this a try.
Let's stop the goals backend container,
which is our node application container here.
And once this is stopped,
let's build the goals node image again,
because we changed the code in there.
And once this was built again,
let's run it again with the same configuration as before,
but now this should connect to MongoDB.
However, I see that it crashed.
It's not up and running here.
So it does not seem to connect
to the MongoDB database successfully.
We can find a solution in the official MongoDB docs,
though, we need to add this off source equals admin
query parameter at the end of the connection string.
So here at the end of this connection string I add
?authsource=admin and if we now build
this goals node image again
we can thereafter run this container successfully.
If I enter, now you'll see we are connected
to MongoDB again.
And with that of course,
our front end application works again and our data is back.