1
00:00:02,320 --> 00:00:04,550
So let's start working on the MongoDB

2
00:00:04,550 --> 00:00:08,029
container and let's make sure that data persists there,

3
00:00:08,029 --> 00:00:10,333
and that we limit the access.

4
00:00:11,380 --> 00:00:13,990
Just to clarify what the problem is.

5
00:00:13,990 --> 00:00:18,990
At the moment, if I Docker stop MongoDB

6
00:00:20,450 --> 00:00:23,610
and keep in mind that we currently have one goal.

7
00:00:23,610 --> 00:00:28,610
If I stop MongoDB and I then rerun it in the same way

8
00:00:28,770 --> 00:00:32,830
as before it works and our application will be able

9
00:00:32,830 --> 00:00:37,030
to talk to it, but the goal is gone.

10
00:00:37,030 --> 00:00:38,920
It's no longer there.

11
00:00:38,920 --> 00:00:42,350
And that happens because when we stop MongoDB,

12
00:00:42,350 --> 00:00:45,760
the container is removed, and when it's removed,

13
00:00:45,760 --> 00:00:48,450
all the data stored in the container is lost.

14
00:00:48,450 --> 00:00:52,350
And the data stored in the database, in the MongoDB database

15
00:00:52,350 --> 00:00:55,360
is stored in that container of course.

16
00:00:55,360 --> 00:00:59,820
So therefore here, we need to ensure that we detach

17
00:00:59,820 --> 00:01:03,200
that data, which in the end is still written

18
00:01:03,200 --> 00:01:04,739
to the hard drive.

19
00:01:04,739 --> 00:01:08,120
Databases also store data on a hard drive somewhere

20
00:01:08,120 --> 00:01:13,120
that that data survives container tear down and removal.

21
00:01:13,220 --> 00:01:14,160
And of course we learned

22
00:01:14,160 --> 00:01:18,240
how we can ensure that data survives.

23
00:01:18,240 --> 00:01:20,133
We can add a volume.

24
00:01:21,050 --> 00:01:23,310
We do this with the dash V flag,

25
00:01:23,310 --> 00:01:27,460
and then we just need to know which path the MongoDB

26
00:01:27,460 --> 00:01:31,920
container uses internally for storing that database data.

27
00:01:31,920 --> 00:01:34,170
And of course, since this isn't our image,

28
00:01:34,170 --> 00:01:38,080
we don't know which path gets used internally,

29
00:01:38,080 --> 00:01:41,630
but we can of course look into the documentation

30
00:01:41,630 --> 00:01:43,840
of this Mongo container.

31
00:01:43,840 --> 00:01:46,750
And there we learn a lot about using this image

32
00:01:46,750 --> 00:01:49,140
and how we can start it and so on,

33
00:01:49,140 --> 00:01:54,140
and we also learn that we can indeed use a volume there.

34
00:01:54,720 --> 00:01:57,690
And what we can see here is that internally,

35
00:01:57,690 --> 00:02:01,620
it seems to be this slash data slash DB folder

36
00:02:01,620 --> 00:02:05,070
in which MongoDB stores the database data,

37
00:02:05,070 --> 00:02:07,883
the database files inside of the container.

38
00:02:08,990 --> 00:02:12,140
Now here in this example, this gets mapped to a bind Mount,

39
00:02:12,140 --> 00:02:15,560
so to a local host machine folder which we know.

40
00:02:15,560 --> 00:02:18,220
This could be useful for being able to inspect

41
00:02:18,220 --> 00:02:21,610
that database conveniently, but we actually don't need

42
00:02:21,610 --> 00:02:24,580
to do that just to persist data.

43
00:02:24,580 --> 00:02:27,530
Instead, all we need to do for that is

44
00:02:27,530 --> 00:02:31,200
as you'll learned in the Volumes and Data Storage section,

45
00:02:31,200 --> 00:02:32,750
a named volume.

46
00:02:32,750 --> 00:02:36,963
So we could name it data and bind this to data/db.

47
00:02:37,940 --> 00:02:40,800
Now that's not a bind mount because we don't have a full

48
00:02:40,800 --> 00:02:43,280
path to a local host machine folder.

49
00:02:43,280 --> 00:02:46,430
Instead we just assign a name and then we map this

50
00:02:46,430 --> 00:02:48,723
to a path instead of the container.

51
00:02:49,560 --> 00:02:52,640
And as you learned, Docker will then create this volume,

52
00:02:52,640 --> 00:02:56,270
if it doesn't exist already and store any data written

53
00:02:56,270 --> 00:02:59,750
inside of the container in that volume on the host machine,

54
00:02:59,750 --> 00:03:02,950
we just don't know where that is on the host machine.

55
00:03:02,950 --> 00:03:06,660
And if it does exist already, Docker will load the data

56
00:03:06,660 --> 00:03:09,700
that's already in that folder on the host machine,

57
00:03:09,700 --> 00:03:11,730
into that folder in the container.

58
00:03:11,730 --> 00:03:15,030
And this then ensures that our data is never lost.

59
00:03:15,030 --> 00:03:17,970
So for now hit enter, I should first of all

60
00:03:17,970 --> 00:03:20,053
stop my MongoDB container of course,

61
00:03:21,000 --> 00:03:23,340
and then try this again and hit enter

62
00:03:23,340 --> 00:03:28,110
to start at MongoDB container again now with this volume.

63
00:03:28,110 --> 00:03:33,000
And that means that now one last time the data is lost,

64
00:03:33,000 --> 00:03:36,290
but if a learn Docker this is saved and persists,

65
00:03:36,290 --> 00:03:40,563
and now it even survives if I stop Mongo again.

66
00:03:41,490 --> 00:03:46,490
If I stop this container again, and I then rerun it,

67
00:03:47,320 --> 00:03:51,210
hence creating a new container, now, if I reload,

68
00:03:51,210 --> 00:03:56,210
you see the data is still there because of that volume.

69
00:03:56,260 --> 00:03:59,360
So that's our data surviving in the MongoDB container,

70
00:03:59,360 --> 00:04:01,943
which is one key requirement we had here.

71
00:04:03,680 --> 00:04:07,290
Now another requirement was security

72
00:04:07,290 --> 00:04:10,500
and preventing access to our database.

73
00:04:10,500 --> 00:04:12,620
And for that the MongoDB image supports

74
00:04:12,620 --> 00:04:16,360
two environment variables, MongoINITDB root username,

75
00:04:16,360 --> 00:04:19,720
and MongoINITDB root password.

76
00:04:19,720 --> 00:04:23,040
And when we use these environment variables,

77
00:04:23,040 --> 00:04:26,330
then the database insert at the MongoDB container will

78
00:04:26,330 --> 00:04:28,560
be created such that this username

79
00:04:28,560 --> 00:04:31,410
and password is required to access it.

80
00:04:31,410 --> 00:04:35,460
And that can of course be convenient because that can ensure

81
00:04:35,460 --> 00:04:39,090
that we need to specify that username and password

82
00:04:39,090 --> 00:04:42,060
in our containers trying to access our database,

83
00:04:42,060 --> 00:04:46,030
which simply adds an extra layer of security.

84
00:04:46,030 --> 00:04:47,710
If we scroll up a bit further,

85
00:04:47,710 --> 00:04:50,590
we see a more detailed usage guide.

86
00:04:50,590 --> 00:04:53,450
So in the end, what we can do here is we can stop

87
00:04:53,450 --> 00:04:58,300
our MongoDB container again, and then run it again

88
00:04:58,300 --> 00:05:02,431
but now by also adding an environment variable,

89
00:05:02,431 --> 00:05:05,640
and the first one which I want to add is MongoINITDB

90
00:05:05,640 --> 00:05:10,640
root username and set it to a value of max, for example,

91
00:05:12,080 --> 00:05:16,030
in my case, and add a second environment variable,

92
00:05:16,030 --> 00:05:19,870
which is this MongoINITDB root password environment

93
00:05:19,870 --> 00:05:24,210
variable, which I will also set to secret here.

94
00:05:24,210 --> 00:05:27,930
Now that's of course not a secure username or password,

95
00:05:27,930 --> 00:05:30,753
but it is good enough here for development.

96
00:05:32,070 --> 00:05:35,790
With that if I hit enter, this now starts up.

97
00:05:35,790 --> 00:05:37,663
This container is now up and running.

98
00:05:38,640 --> 00:05:43,390
And if we now reload here, you see fetching data fails.

99
00:05:43,390 --> 00:05:46,260
And that fails because the node application,

100
00:05:46,260 --> 00:05:48,136
which talks to MongoDB,

101
00:05:48,136 --> 00:05:51,560
connected without that password and user

102
00:05:51,560 --> 00:05:54,093
and now that database is protected though.

103
00:05:55,220 --> 00:05:59,050
So now we need to ensure that in our app JS file

104
00:05:59,050 --> 00:06:01,230
of our node backend,

105
00:06:01,230 --> 00:06:05,260
indeed we do utilize that password and username

106
00:06:05,260 --> 00:06:08,530
we just used for starting the database.

107
00:06:08,530 --> 00:06:11,853
So max in my case and secret as a password.

108
00:06:13,670 --> 00:06:17,400
And for that we can manipulate this connection string a bit

109
00:06:17,400 --> 00:06:20,300
because this Mongo DB connection string

110
00:06:20,300 --> 00:06:23,110
has a special format which is understood

111
00:06:23,110 --> 00:06:25,950
by MongoDB in the end,

112
00:06:25,950 --> 00:06:30,300
The format is such that we can have a username and password,

113
00:06:30,300 --> 00:06:34,690
which we add in front of the actual host address by having

114
00:06:34,690 --> 00:06:39,560
username then a colon, then password and then I add symbol.

115
00:06:39,560 --> 00:06:42,110
This is optional, but now we need it,

116
00:06:42,110 --> 00:06:45,510
since we now do have a username and a password.

117
00:06:45,510 --> 00:06:50,510
So in my case would be max:secret@mongodb.

118
00:06:50,890 --> 00:06:53,910
And with this now, if we rebuild the node image

119
00:06:53,910 --> 00:06:55,830
and then restart the container,

120
00:06:55,830 --> 00:06:58,090
we should be able to connect again.

121
00:06:58,090 --> 00:06:59,940
So let's give this a try.

122
00:06:59,940 --> 00:07:04,100
Let's stop the goals backend container,

123
00:07:04,100 --> 00:07:06,863
which is our node application container here.

124
00:07:07,760 --> 00:07:10,880
And once this is stopped,

125
00:07:10,880 --> 00:07:13,300
let's build the goals node image again,

126
00:07:13,300 --> 00:07:15,493
because we changed the code in there.

127
00:07:16,810 --> 00:07:19,450
And once this was built again,

128
00:07:19,450 --> 00:07:24,450
let's run it again with the same configuration as before,

129
00:07:24,660 --> 00:07:28,760
but now this should connect to MongoDB.

130
00:07:28,760 --> 00:07:30,930
However, I see that it crashed.

131
00:07:30,930 --> 00:07:32,810
It's not up and running here.

132
00:07:32,810 --> 00:07:35,020
So it does not seem to connect

133
00:07:35,020 --> 00:07:37,543
to the MongoDB database successfully.

134
00:07:38,660 --> 00:07:41,650
We can find a solution in the official MongoDB docs,

135
00:07:41,650 --> 00:07:46,430
though, we need to add this off source equals admin

136
00:07:46,430 --> 00:07:50,060
query parameter at the end of the connection string.

137
00:07:50,060 --> 00:07:52,417
So here at the end of this connection string I add

138
00:07:52,417 --> 00:07:57,417
?authsource=admin and if we now build

139
00:07:58,450 --> 00:08:00,760
this goals node image again

140
00:08:00,760 --> 00:08:04,250
we can thereafter run this container successfully.

141
00:08:04,250 --> 00:08:06,850
If I enter, now you'll see we are connected

142
00:08:06,850 --> 00:08:08,820
to MongoDB again.

143
00:08:08,820 --> 00:08:10,830
And with that of course,

144
00:08:10,830 --> 00:08:14,503
our front end application works again and our data is back.

