1
00:00:02,390 --> 00:00:04,500
So now we learn about volumes,

2
00:00:04,500 --> 00:00:07,720
and specifically named volumes are useful.

3
00:00:07,720 --> 00:00:09,780
Anonymous volumes, I would say,

4
00:00:09,780 --> 00:00:12,890
their use is not entirely clear yet.

5
00:00:12,890 --> 00:00:14,360
I'll come back to those.

6
00:00:14,360 --> 00:00:17,700
But I actually now wanna dive into bind mounts first,

7
00:00:17,700 --> 00:00:20,980
before we have a look at anonymous volumes again.

8
00:00:20,980 --> 00:00:23,210
Because bind mounts, can help us with

9
00:00:23,210 --> 00:00:26,083
a different kind of problem we might be facing.

10
00:00:27,120 --> 00:00:30,540
And here is the kind of problem we might be facing.

11
00:00:30,540 --> 00:00:33,940
Whenever we change anything in our source code,

12
00:00:33,940 --> 00:00:38,890
be that in the server JS file, or in any HTML file here,

13
00:00:38,890 --> 00:00:42,570
those changes are not reflected in the running container

14
00:00:42,570 --> 00:00:45,300
unless we rebuild the image.

15
00:00:45,300 --> 00:00:48,600
I mean, we do have a running application here.

16
00:00:48,600 --> 00:00:51,770
And if I go back to localhost 3000,

17
00:00:51,770 --> 00:00:56,360
it's actually the feedback HTML file which is loaded.

18
00:00:56,360 --> 00:01:01,360
But if I add, please here, after your feedback,

19
00:01:01,390 --> 00:01:04,840
and I save this file, if I reload here,

20
00:01:04,840 --> 00:01:07,400
we don't see please on the page.

21
00:01:07,400 --> 00:01:09,710
And it should be clear why this is happening.

22
00:01:09,710 --> 00:01:13,730
I emphasized this a lot in the last module and this module,

23
00:01:13,730 --> 00:01:16,600
we only copy a snapshot off this folder,

24
00:01:16,600 --> 00:01:19,060
into the Docker image when it's created,

25
00:01:19,060 --> 00:01:22,350
and subsequent changes to anything in that folder,

26
00:01:22,350 --> 00:01:25,130
will therefore not be reflected in the image,

27
00:01:25,130 --> 00:01:27,940
and therefore also not in the container.

28
00:01:27,940 --> 00:01:31,380
But of course, during development, if we're using Docker,

29
00:01:31,380 --> 00:01:33,440
it would be pretty important to us,

30
00:01:33,440 --> 00:01:36,200
that such changes are reflected.

31
00:01:36,200 --> 00:01:38,600
Because otherwise, we always have

32
00:01:38,600 --> 00:01:42,820
to rebuild the entire image and restart a container,

33
00:01:42,820 --> 00:01:44,640
whenever we change anything.

34
00:01:44,640 --> 00:01:48,170
And of course, during development, we tend to change a lot.

35
00:01:48,170 --> 00:01:51,940
So restarting everything all the time is pretty cumbersome.

36
00:01:51,940 --> 00:01:54,500
That's where bind mounts can help us.

37
00:01:54,500 --> 00:01:57,900
Bind mounts have some similarities with volumes,

38
00:01:57,900 --> 00:02:00,130
but there is one key difference.

39
00:02:00,130 --> 00:02:03,410
Where volumes are managed by Docker,

40
00:02:03,410 --> 00:02:05,680
and we don't really know where

41
00:02:05,680 --> 00:02:08,570
on our host machine file system they are.

42
00:02:08,570 --> 00:02:10,840
For bind mounts, we do know it.

43
00:02:10,840 --> 00:02:14,110
Because for bind mounts, we, as a developer,

44
00:02:14,110 --> 00:02:17,580
set the path to which the container internal path

45
00:02:17,580 --> 00:02:20,230
should be mapped on our host machine.

46
00:02:20,230 --> 00:02:22,960
So here, we're fully aware off the path

47
00:02:22,960 --> 00:02:24,810
on our localhost machine.

48
00:02:24,810 --> 00:02:26,388
And since that is the case,

49
00:02:26,388 --> 00:02:29,570
and containers cannot just write to volumes,

50
00:02:29,570 --> 00:02:31,300
but also read from there,

51
00:02:31,300 --> 00:02:34,160
of course we could put our source code

52
00:02:34,160 --> 00:02:36,000
into such a bind mount.

53
00:02:36,000 --> 00:02:39,130
And if we do that, we could then make sure that

54
00:02:39,130 --> 00:02:41,020
the container is aware of that,

55
00:02:41,020 --> 00:02:44,720
and that the source code is actually not used

56
00:02:44,720 --> 00:02:47,180
from that copied in snapshot,

57
00:02:47,180 --> 00:02:49,560
but instead from that bind mount.

58
00:02:49,560 --> 00:02:54,250
So from that connection to some folder on our host machine.

59
00:02:54,250 --> 00:02:56,853
And therefore the container would always have access

60
00:02:56,853 --> 00:02:58,650
to the latest code.

61
00:02:58,650 --> 00:03:02,990
And not just to the snapshot we put into our image here

62
00:03:02,990 --> 00:03:05,170
when it was created at the beginning.

63
00:03:05,170 --> 00:03:08,160
So bind mounts are therefore perfect,

64
00:03:08,160 --> 00:03:11,390
for persistent and editable data.

65
00:03:11,390 --> 00:03:14,370
And that's the difference to normal volumes.

66
00:03:14,370 --> 00:03:17,600
A named volume can help us with persistent data,

67
00:03:17,600 --> 00:03:21,050
but editing is not really possible, since we don't know

68
00:03:21,050 --> 00:03:23,633
where it's stored on our host machine.

69
00:03:25,070 --> 00:03:28,620
So how can we then add such a bind mount?

70
00:03:28,620 --> 00:03:30,310
Again, it's not something we can do

71
00:03:30,310 --> 00:03:32,170
from inside the Docker file.

72
00:03:32,170 --> 00:03:35,940
Because it's actually specific to a container which you run,

73
00:03:35,940 --> 00:03:38,720
not to the image, it doesn't affect the image,

74
00:03:38,720 --> 00:03:40,720
it just affects the container.

75
00:03:40,720 --> 00:03:44,500
And therefore, we have to set up a bind mount

76
00:03:44,500 --> 00:03:47,763
from inside the terminal when we run our container.

77
00:03:48,650 --> 00:03:51,080
So for that, first of all, I'll stop.

78
00:03:51,080 --> 00:03:53,490
I'll stop my currently running container

79
00:03:53,490 --> 00:03:56,160
with Docker stop feedback app.

80
00:03:56,160 --> 00:03:59,420
And once this is stopped, I will rerun it,

81
00:03:59,420 --> 00:04:02,130
I will create a new container in the same way,

82
00:04:02,130 --> 00:04:04,860
by using Docker run.

83
00:04:04,860 --> 00:04:07,310
But now I'll add more than one volume,

84
00:04:07,310 --> 00:04:11,720
not just this one named volume, but a second volume,

85
00:04:11,720 --> 00:04:15,120
simply by again adding dash V.

86
00:04:15,120 --> 00:04:16,560
And now there is a line break,

87
00:04:16,560 --> 00:04:19,829
but it's dash V and then a whitespace.

88
00:04:19,829 --> 00:04:21,029
So a blank.

89
00:04:21,029 --> 00:04:25,130
And then again, a volume as we added it before.

90
00:04:25,130 --> 00:04:27,210
But now here's the key difference.

91
00:04:27,210 --> 00:04:30,810
The folder to which I wanna map it inside of the container,

92
00:04:30,810 --> 00:04:33,490
is just slash app, of course.

93
00:04:33,490 --> 00:04:36,250
So just slash app, because I'm also copying

94
00:04:36,250 --> 00:04:39,700
all my source code into just slash app here.

95
00:04:39,700 --> 00:04:43,270
So I wanna control the entire app folder now.

96
00:04:43,270 --> 00:04:45,550
But, and that's the difference.

97
00:04:45,550 --> 00:04:48,560
The name which I now assign in front of the colon,

98
00:04:48,560 --> 00:04:51,260
is now not app or anything like that.

99
00:04:51,260 --> 00:04:56,260
Instead it is a path to the folder on my host machine,

100
00:04:56,650 --> 00:04:59,910
where I have all the code, all the content,

101
00:04:59,910 --> 00:05:03,210
that should go into this mapped folder.

102
00:05:03,210 --> 00:05:07,970
And this must be an absolute path here, not a relative one.

103
00:05:07,970 --> 00:05:10,700
You can get such a path here in Visual Studio Code

104
00:05:10,700 --> 00:05:13,660
by right clicking on server JS, for example,

105
00:05:13,660 --> 00:05:15,733
and choosing copy path.

106
00:05:16,770 --> 00:05:20,180
Choose that, and added in front of the colon.

107
00:05:20,180 --> 00:05:23,230
Yes, it's quite long, but that is what we need.

108
00:05:23,230 --> 00:05:25,640
Make sure you remove the file at the end though,

109
00:05:25,640 --> 00:05:29,670
it should just be the path to your project folder.

110
00:05:29,670 --> 00:05:33,620
So your project folder name should be the last thing here.

111
00:05:33,620 --> 00:05:38,220
In this case, at least, you can also bind a single file,

112
00:05:38,220 --> 00:05:41,840
in case you just wanna share a single file with a container,

113
00:05:41,840 --> 00:05:44,090
you can bind a file to a file.

114
00:05:44,090 --> 00:05:46,090
But here when I wanna bind to a folder,

115
00:05:46,090 --> 00:05:48,400
and therefore I wanna bind a complete folder

116
00:05:48,400 --> 00:05:52,790
on my hosting machine to this app folder in the container.

117
00:05:52,790 --> 00:05:55,290
That's why we're removing the file name at the end.

118
00:05:55,290 --> 00:05:57,960
Because I don't just wanna share the file,

119
00:05:57,960 --> 00:05:59,853
I wanna share the complete folder.

120
00:06:01,030 --> 00:06:04,700
You might also wanna consider putting this into quotes,

121
00:06:04,700 --> 00:06:07,630
this entire statement here.

122
00:06:07,630 --> 00:06:12,630
So your absolute path, the colon, and the MapPath,

123
00:06:12,770 --> 00:06:16,040
to ensure that it doesn't break in case your path

124
00:06:16,040 --> 00:06:18,513
includes special characters or whitespace.

125
00:06:19,440 --> 00:06:23,230
Mine doesn't, except for the slashes, which are okay.

126
00:06:23,230 --> 00:06:25,470
But if your path has some blanks in it

127
00:06:25,470 --> 00:06:28,700
or anything like that, simply wrap everything here,

128
00:06:28,700 --> 00:06:32,520
the entire volume mapping with quotes.

129
00:06:32,520 --> 00:06:35,560
Now, one important note about bind mounts

130
00:06:35,560 --> 00:06:39,770
and mounting folders, which you know, into containers.

131
00:06:39,770 --> 00:06:43,250
You should make sure that Docker has access to the folder

132
00:06:43,250 --> 00:06:45,200
which you're sharing as a bind mount.

133
00:06:45,200 --> 00:06:50,170
And you can do this by accessing the preferences of Docker,

134
00:06:50,170 --> 00:06:52,620
by using that running Docker service,

135
00:06:52,620 --> 00:06:55,263
this Docker process you started.

136
00:06:56,280 --> 00:07:01,280
And there, make sure that under Resources file sharing,

137
00:07:01,700 --> 00:07:05,950
your folder which you are sharing right now, is listed here.

138
00:07:05,950 --> 00:07:08,400
It doesn't have to be the full folder,

139
00:07:08,400 --> 00:07:10,440
but it should be a parent folder,

140
00:07:10,440 --> 00:07:12,540
of the folder you're sharing.

141
00:07:12,540 --> 00:07:17,540
If you don't have this file sharing area under Resources,

142
00:07:17,540 --> 00:07:19,510
you are most likely on windows

143
00:07:19,510 --> 00:07:22,450
and their you don't have this option,

144
00:07:22,450 --> 00:07:25,050
you don't have this area in the settings.

145
00:07:25,050 --> 00:07:30,050
If you are running Docker with help of the WSL integration,

146
00:07:30,380 --> 00:07:32,500
you might remember the setup lecture,

147
00:07:32,500 --> 00:07:35,110
from the first course section.

148
00:07:35,110 --> 00:07:37,600
Well, if that option is missing, that's no problem,

149
00:07:37,600 --> 00:07:40,610
it's missing because you won't have any problems

150
00:07:40,610 --> 00:07:44,320
with file sharing anyways, with the setup you're using,

151
00:07:44,320 --> 00:07:46,240
so you're fine.

152
00:07:46,240 --> 00:07:50,370
Now if you should be using Docker Toolbox to run Docker,

153
00:07:50,370 --> 00:07:54,260
then by default your users folder will be shared,

154
00:07:54,260 --> 00:07:56,580
and attached you find a link to an article

155
00:07:56,580 --> 00:08:00,750
which explains how you can share other folders as well.

156
00:08:00,750 --> 00:08:02,610
So that is what you should do then,

157
00:08:02,610 --> 00:08:06,180
if you are using Docker Toolbox to ensure that,

158
00:08:06,180 --> 00:08:09,260
Docker is able to really write to your

159
00:08:09,260 --> 00:08:13,150
localhost system machine for the given folder

160
00:08:13,150 --> 00:08:16,220
you wanna use as a volume in your container.

161
00:08:16,220 --> 00:08:18,040
So the attached link is for you,

162
00:08:18,040 --> 00:08:20,743
if you are using Docker Toolbox.

163
00:08:21,620 --> 00:08:24,890
So in my case, for example, the project I'm sharing

164
00:08:24,890 --> 00:08:28,630
is in some sub folder of my users directory.

165
00:08:28,630 --> 00:08:31,180
And that will be accessible by Docker,

166
00:08:31,180 --> 00:08:35,720
because it's listed here, under file sharing Resources.

167
00:08:35,720 --> 00:08:38,409
Now if your project is in some folder,

168
00:08:38,409 --> 00:08:41,590
which is not a sub folder of one of the resources

169
00:08:41,590 --> 00:08:43,780
specified here, you should make sure

170
00:08:43,780 --> 00:08:46,430
that you add your project folder,

171
00:08:46,430 --> 00:08:49,110
or a parent folder of it, even better,

172
00:08:49,110 --> 00:08:51,620
as a shareable resource in this list

173
00:08:51,620 --> 00:08:54,453
in your Docker preferences, that's important.

174
00:08:56,010 --> 00:09:00,340
And if we now hit enter, this starts the container again.

175
00:09:00,340 --> 00:09:03,050
And now our entire folders here,

176
00:09:03,050 --> 00:09:06,920
will be mounted as a volume, into the app folder,

177
00:09:06,920 --> 00:09:08,223
inside of the container.

178
00:09:09,230 --> 00:09:13,700
Nonetheless, you'll notice if you reload, that it crashes.

179
00:09:13,700 --> 00:09:15,940
And if we inspect our running

180
00:09:15,940 --> 00:09:18,770
and shutdown containers thereafter,

181
00:09:18,770 --> 00:09:21,805
we see this container is nowhere to be found.

182
00:09:21,805 --> 00:09:24,350
And we don't find it in the closed containers,

183
00:09:24,350 --> 00:09:26,580
in the stopped containers,

184
00:09:26,580 --> 00:09:29,680
because we remove all containers which are shut down.

185
00:09:29,680 --> 00:09:31,300
But this of course also means that,

186
00:09:31,300 --> 00:09:33,130
it seems to shut down immediately.

187
00:09:33,130 --> 00:09:35,363
So something seems to be very wrong here.

188
00:09:36,210 --> 00:09:39,200
And to find out what's wrong, I'll restart it again.

189
00:09:39,200 --> 00:09:41,840
But now without dash, dash RM,

190
00:09:41,840 --> 00:09:43,710
to not automatically remove it

191
00:09:43,710 --> 00:09:45,340
when it shuts down.

192
00:09:45,340 --> 00:09:50,340
And thereafter we see it here, under stopped containers.

193
00:09:50,440 --> 00:09:54,920
And we can now use Docker logs, to look into our container,

194
00:09:54,920 --> 00:09:56,973
to see the error that was thrown.

195
00:09:59,190 --> 00:10:01,220
And we see that the problem is,

196
00:10:01,220 --> 00:10:05,090
that it fails to find the module Express.

197
00:10:05,090 --> 00:10:07,940
And that simply means that our node code

198
00:10:07,940 --> 00:10:10,240
doesn't even start executing,

199
00:10:10,240 --> 00:10:13,590
because an important dependency is missing.

200
00:10:13,590 --> 00:10:15,940
Now up to this point, it always worked, of course.

201
00:10:15,940 --> 00:10:19,520
And after all, we are installing all dependencies

202
00:10:19,520 --> 00:10:22,960
with the npm install instruction in the Docker file.

203
00:10:22,960 --> 00:10:24,453
So why is it missing now?

204
00:10:25,750 --> 00:10:27,790
Well, that has something to do with

205
00:10:27,790 --> 00:10:29,840
our newly added bind mount.

206
00:10:29,840 --> 00:10:34,190
With this bind mount that binds our entire project folder

207
00:10:34,190 --> 00:10:35,740
to the app folder.

208
00:10:35,740 --> 00:10:38,770
And we'll see what's wrong and how to solve the problem,

209
00:10:38,770 --> 00:10:40,003
in the next lecture.

