1
00:00:02,220 --> 00:00:03,053
And for this,

2
00:00:03,053 --> 00:00:06,040
we could add a nginx.dockerfile here

3
00:00:06,040 --> 00:00:08,290
in our dockerfiles folder.

4
00:00:08,290 --> 00:00:13,290
And we could grab this nginx:stable-alpine image here

5
00:00:13,660 --> 00:00:15,380
as a base image,

6
00:00:15,380 --> 00:00:17,420
then set the working directory

7
00:00:17,420 --> 00:00:22,420
to our configuration folder here,

8
00:00:23,360 --> 00:00:26,450
so this one without the filename at the end,

9
00:00:26,450 --> 00:00:28,520
just this folder,

10
00:00:28,520 --> 00:00:31,530
and add this as a working directory here

11
00:00:31,530 --> 00:00:35,730
so that thereafter we can copy our local configuration file,

12
00:00:35,730 --> 00:00:39,110
this nginx.conf file in the nginx folder

13
00:00:39,110 --> 00:00:41,160
into that working directory.

14
00:00:41,160 --> 00:00:44,580
We can do that by copying nginx,

15
00:00:44,580 --> 00:00:47,927
which is this folder name that holds the configuration,

16
00:00:47,927 --> 00:00:52,927
/nginx.conf into ., so into that working directory.

17
00:00:54,810 --> 00:00:57,830
And thereafter, I also want to run a command

18
00:00:57,830 --> 00:01:02,330
because my config file here is named nginx.conf,

19
00:01:02,330 --> 00:01:06,070
but it should actually be named default.conf

20
00:01:06,070 --> 00:01:07,230
inside of the container.

21
00:01:07,230 --> 00:01:10,450
That is what nginx expects there.

22
00:01:10,450 --> 00:01:14,720
Now, we could rename it here in our local nginx folder,

23
00:01:14,720 --> 00:01:17,730
or we run a command in the container

24
00:01:17,730 --> 00:01:22,730
which renames that nginx.conf file after it was copied in.

25
00:01:23,000 --> 00:01:25,840
And we can do this with the move command, mv,

26
00:01:25,840 --> 00:01:29,280
which is available on Linux on which this container runs.

27
00:01:29,280 --> 00:01:32,010
And then we can move

28
00:01:32,010 --> 00:01:33,470
and therefore rename

29
00:01:33,470 --> 00:01:38,470
the etc/nginx/conf.d/nginx.conf file

30
00:01:40,130 --> 00:01:42,960
or, since that's already our working directory,

31
00:01:42,960 --> 00:01:45,220
just this nginx.conf file

32
00:01:45,220 --> 00:01:47,040
because we already are executing

33
00:01:47,040 --> 00:01:48,810
this command in this folder,

34
00:01:48,810 --> 00:01:53,250
and move it and therefore rename it to default.conf

35
00:01:53,250 --> 00:01:55,440
in that same working directory.

36
00:01:55,440 --> 00:01:58,040
And this command will simply rename nginx.conf,

37
00:01:58,040 --> 00:02:01,943
which is the file we copied in, to default.conf.

38
00:02:02,930 --> 00:02:05,290
And thereafter, we could switch our working directory

39
00:02:05,290 --> 00:02:10,289
to our www/html and all the copy in our source code

40
00:02:11,470 --> 00:02:14,400
by copying in the src folder,

41
00:02:14,400 --> 00:02:17,090
so this folder here,

42
00:02:17,090 --> 00:02:20,520
into ., so into our working directory.

43
00:02:20,520 --> 00:02:22,900
So everything in the src folder is copied

44
00:02:22,900 --> 00:02:24,720
into our working directory.

45
00:02:24,720 --> 00:02:26,423
That's something we could do here.

46
00:02:27,600 --> 00:02:30,840
And by doing that, by adding this dockerfile,

47
00:02:30,840 --> 00:02:34,470
we ensure that we always copy in a snapshot

48
00:02:34,470 --> 00:02:38,840
of our configuration and of our source code into the image,

49
00:02:38,840 --> 00:02:41,683
and we're not relying on just the bind mount.

50
00:02:42,530 --> 00:02:44,910
The bind mount will still help us thereafter

51
00:02:44,910 --> 00:02:45,960
during development

52
00:02:45,960 --> 00:02:49,130
so that the latest code and the latest configuration

53
00:02:49,130 --> 00:02:51,080
is bound into that container.

54
00:02:51,080 --> 00:02:53,200
But if we should deploy this container,

55
00:02:53,200 --> 00:02:55,090
we'll not have these bind mounts,

56
00:02:55,090 --> 00:02:58,070
and then the snapshots copied into the image

57
00:02:58,070 --> 00:02:59,560
will become important.

58
00:02:59,560 --> 00:03:00,650
So that's a little tweak,

59
00:03:00,650 --> 00:03:02,500
a little addition we could make here.

60
00:03:03,660 --> 00:03:07,238
Now, we don't need to specify an entry point or a command

61
00:03:07,238 --> 00:03:09,360
in this dockerfile here

62
00:03:09,360 --> 00:03:13,310
because the nginx image already has a default command.

63
00:03:13,310 --> 00:03:15,920
And if we don't specify our own one,

64
00:03:15,920 --> 00:03:18,600
the default one will be executed.

65
00:03:18,600 --> 00:03:21,280
And that will be the one to start this web server,

66
00:03:21,280 --> 00:03:22,903
which is exactly what I want.

67
00:03:23,970 --> 00:03:27,180
So now we just need to go to docker-compose.yaml

68
00:03:27,180 --> 00:03:29,640
and tweak our code up here.

69
00:03:29,640 --> 00:03:32,240
Instead of using just that base image,

70
00:03:32,240 --> 00:03:34,240
we now wanna use our own image,

71
00:03:34,240 --> 00:03:37,150
and hence, we need the build configuration.

72
00:03:37,150 --> 00:03:40,270
And now here's something which is also very important

73
00:03:40,270 --> 00:03:42,390
because we'll now use some code here

74
00:03:42,390 --> 00:03:46,093
or a certain configuration which we haven't used before.

75
00:03:47,010 --> 00:03:48,660
Previously, we always had something

76
00:03:48,660 --> 00:03:50,407
like context: ., dockerfile:,

77
00:03:51,870 --> 00:03:54,290
and then the name of the dockerfile.

78
00:03:54,290 --> 00:03:55,920
Or to be precise,

79
00:03:55,920 --> 00:03:59,570
in our build configurations in this file,

80
00:03:59,570 --> 00:04:03,210
our context was the dockerfiles folder

81
00:04:03,210 --> 00:04:05,040
since that holds the dockerfiles,

82
00:04:05,040 --> 00:04:07,200
and then we specify the name here.

83
00:04:07,200 --> 00:04:09,970
For example, nginx.dockerfile.

84
00:04:11,340 --> 00:04:13,100
Now, that won't work here

85
00:04:13,100 --> 00:04:17,820
because the context does more than just set the folder

86
00:04:17,820 --> 00:04:20,690
in which this dockerfile can be found.

87
00:04:20,690 --> 00:04:22,780
It also sets the folder

88
00:04:22,780 --> 00:04:25,420
in which the dockerfile will be built.

89
00:04:25,420 --> 00:04:27,010
And that matters.

90
00:04:27,010 --> 00:04:30,910
In this dockerfile, I'm referring to the nginx folder,

91
00:04:30,910 --> 00:04:33,130
and I'm referring to the src folder

92
00:04:33,130 --> 00:04:36,300
in my host machine project folder.

93
00:04:36,300 --> 00:04:39,710
And both folders, nginx and src,

94
00:04:39,710 --> 00:04:43,140
are outside of the dockerfiles folder.

95
00:04:43,140 --> 00:04:46,390
So if I set dockerfiles as my context

96
00:04:46,390 --> 00:04:49,460
and the dockerfile is built in that folder,

97
00:04:49,460 --> 00:04:53,350
nginx and src are unreachable,

98
00:04:53,350 --> 00:04:56,080
and hence, building this image would fail.

99
00:04:56,080 --> 00:04:57,990
So what we actually need to do here

100
00:04:57,990 --> 00:05:00,470
is we need to set the context to .,

101
00:05:00,470 --> 00:05:04,260
which means the same folder as docker-compose.yaml is in,

102
00:05:04,260 --> 00:05:06,350
which is our entire project folder,

103
00:05:06,350 --> 00:05:09,520
and then add the path to the dockerfile here

104
00:05:09,520 --> 00:05:11,650
on the dockerfile instruction.

105
00:05:11,650 --> 00:05:14,723
So now that's dockerfiles/nginx.dockerfile.

106
00:05:17,770 --> 00:05:20,590
By doing that, we ensure that more context,

107
00:05:20,590 --> 00:05:22,880
more folders, are available

108
00:05:22,880 --> 00:05:26,290
because the dockerfile is built in the main project folder

109
00:05:26,290 --> 00:05:28,783
and not inside of the dockerfiles folder.

110
00:05:29,680 --> 00:05:33,630
For the other images, like the php image, this didn't matter

111
00:05:33,630 --> 00:05:35,140
because in the php image,

112
00:05:35,140 --> 00:05:37,950
we're not copying anything from our host machine,

113
00:05:37,950 --> 00:05:41,080
and therefore they're using this context was fine.

114
00:05:41,080 --> 00:05:43,570
But if you need something else from your project folder,

115
00:05:43,570 --> 00:05:47,600
setting the context to some child folder will not work.

116
00:05:47,600 --> 00:05:49,040
So that's important.

117
00:05:49,040 --> 00:05:52,060
Now, we could already try that, but before we do that,

118
00:05:52,060 --> 00:05:54,040
there's also something else I wanna do.

119
00:05:54,040 --> 00:05:56,560
For one, I'll comment out these volumes

120
00:05:56,560 --> 00:06:00,310
so that we try running this without our bind mounts,

121
00:06:00,310 --> 00:06:03,860
which means that source code changes won't be reflected,

122
00:06:03,860 --> 00:06:06,430
but we should still see our starting page,

123
00:06:06,430 --> 00:06:08,140
changes won't be reflected though,

124
00:06:08,140 --> 00:06:09,950
but the starting page should be there

125
00:06:09,950 --> 00:06:13,090
since we copy a snapshot into our container.

126
00:06:13,090 --> 00:06:14,060
But besides that,

127
00:06:14,060 --> 00:06:18,660
I also wanna tweak that php.dockerfile here

128
00:06:18,660 --> 00:06:21,570
because here it's very similar.

129
00:06:21,570 --> 00:06:23,680
I'm also setting this bind mount,

130
00:06:23,680 --> 00:06:25,710
which is great during development,

131
00:06:25,710 --> 00:06:29,270
but which won't help us if we ever should deploy this

132
00:06:29,270 --> 00:06:31,140
because then this php.dockerfile

133
00:06:32,070 --> 00:06:35,500
actually will have no code inside of it.

134
00:06:35,500 --> 00:06:38,960
And that, of course, means that no code would be part

135
00:06:38,960 --> 00:06:41,690
of the deploy php container.

136
00:06:41,690 --> 00:06:43,170
So what we wanna do here

137
00:06:43,170 --> 00:06:46,920
is we also wanna copy the src folder into .,

138
00:06:46,920 --> 00:06:51,070
so into this working directory, /var/www/html,

139
00:06:51,070 --> 00:06:53,950
so that our source code, a snapshot of it,

140
00:06:53,950 --> 00:06:55,633
is also available here.

141
00:06:57,230 --> 00:06:59,550
And that means that we now also should be able

142
00:06:59,550 --> 00:07:02,780
to run this php container without this bind mount.

143
00:07:02,780 --> 00:07:05,190
Again, the disadvantage without the bind mount

144
00:07:05,190 --> 00:07:08,780
is that changes to our source code are not reflected,

145
00:07:08,780 --> 00:07:10,950
and we would need to rebuild the image,

146
00:07:10,950 --> 00:07:12,320
but this is just a demo.

147
00:07:12,320 --> 00:07:14,940
We'll comment it back in for development later.

148
00:07:14,940 --> 00:07:17,840
I just want to show you how we could not also run it

149
00:07:17,840 --> 00:07:20,893
such that it would be deployment-ready, so to say.

150
00:07:22,220 --> 00:07:25,580
Now, since my php.dockerfile now does refer

151
00:07:25,580 --> 00:07:27,820
to a folder in the project folder,

152
00:07:27,820 --> 00:07:30,810
we also need to adjust our context here now

153
00:07:30,810 --> 00:07:34,600
and instead adjust the dockerfile to include the path

154
00:07:34,600 --> 00:07:38,103
so that the build context is more than just a child folder.

155
00:07:39,660 --> 00:07:41,470
Now, we don't need to change anything

156
00:07:41,470 --> 00:07:43,150
about the other services

157
00:07:43,150 --> 00:07:46,550
because composer, artisan, and npm

158
00:07:46,550 --> 00:07:50,780
are essentially just meant to be executed locally here,

159
00:07:50,780 --> 00:07:52,143
at least at the moment,

160
00:07:53,200 --> 00:07:55,707
so we don't need to change anything here.

161
00:07:55,707 --> 00:07:58,200
And mysql has no bind volume.

162
00:07:58,200 --> 00:08:00,773
This image and container should work just fine.

163
00:08:02,440 --> 00:08:04,320
So if we now save this

164
00:08:04,320 --> 00:08:08,980
and we run docker-composer up -d --build

165
00:08:08,980 --> 00:08:13,890
to force a re-evaluation of all images, of all dockerfiles,

166
00:08:13,890 --> 00:08:17,083
and then we run the server service,

167
00:08:18,670 --> 00:08:22,950
and I type docker-compose instead of docker-composer,

168
00:08:22,950 --> 00:08:25,760
this is now building the php image again

169
00:08:25,760 --> 00:08:28,360
because we're copying in the source code now.

170
00:08:28,360 --> 00:08:31,003
So let's now wait for all of that to finish.

171
00:08:31,840 --> 00:08:34,543
And this is now looking good.

172
00:08:35,480 --> 00:08:40,350
If I now reload localhost:8000, I get an error though.

173
00:08:40,350 --> 00:08:42,780
Permission denied.

174
00:08:42,780 --> 00:08:47,650
And that error is related to the php image

175
00:08:47,650 --> 00:08:50,340
which we're using in a php.dockerfile.

176
00:08:50,340 --> 00:08:52,710
We're also copying our source code

177
00:08:52,710 --> 00:08:54,630
into this working directory here.

178
00:08:54,630 --> 00:08:57,770
And the problem we have is that once the container

179
00:08:57,770 --> 00:09:01,200
is generally able to read and write,

180
00:09:01,200 --> 00:09:04,140
this image actually restricts

181
00:09:04,140 --> 00:09:06,530
read and write access by the container.

182
00:09:06,530 --> 00:09:09,850
This wasn't a problem with the bind mount

183
00:09:09,850 --> 00:09:12,050
which we used before,

184
00:09:12,050 --> 00:09:16,170
but it is a problem if we work only inside of the container

185
00:09:16,170 --> 00:09:18,210
as we're doing it now.

186
00:09:18,210 --> 00:09:22,690
The solution is to give our container write access

187
00:09:22,690 --> 00:09:26,940
to certain folders to be precise to our source code folder,

188
00:09:26,940 --> 00:09:29,000
our working directory here.

189
00:09:29,000 --> 00:09:31,410
And we can do this by running a number of command

190
00:09:31,410 --> 00:09:33,480
instead of the image when it's being created,

191
00:09:33,480 --> 00:09:35,593
and that's the chown command,

192
00:09:38,760 --> 00:09:42,760
which is a Linux command for changing folder ownership

193
00:09:42,760 --> 00:09:46,903
and controlling who's allowed to read or write to folders.

194
00:09:47,780 --> 00:09:50,940
And we wanna add the -R flag here,

195
00:09:50,940 --> 00:09:52,390
which in the end is just as needed

196
00:09:52,390 --> 00:09:55,040
to change the ownership of an entire folder

197
00:09:55,040 --> 00:09:56,320
by doing it recursively

198
00:09:56,320 --> 00:09:59,400
for all folders and files inside of it.

199
00:09:59,400 --> 00:10:00,240
And now here we need

200
00:10:00,240 --> 00:10:02,830
to give a special user more permissions,

201
00:10:02,830 --> 00:10:07,070
and that special user is the www-data user,

202
00:10:07,070 --> 00:10:11,143
which is the default user created by this php image.

203
00:10:12,190 --> 00:10:14,580
And that's the default user who, by default,

204
00:10:14,580 --> 00:10:19,020
has no write access to this working directory.

205
00:10:19,020 --> 00:10:21,860
So now here we need to add a colon

206
00:10:21,860 --> 00:10:24,510
and then repeat that username in the end

207
00:10:24,510 --> 00:10:27,630
to control that this user has read and write access,

208
00:10:27,630 --> 00:10:29,770
and then specify the folder name,

209
00:10:29,770 --> 00:10:33,023
in this case /var/www/html.

210
00:10:33,960 --> 00:10:35,360
And this might look strange,

211
00:10:35,360 --> 00:10:38,420
especially if you have no experience with Linux commands.

212
00:10:38,420 --> 00:10:41,300
It simply ensures that this default user,

213
00:10:41,300 --> 00:10:43,500
which is set up by this php image,

214
00:10:43,500 --> 00:10:48,500
has write access to this folder which holds our source code.

215
00:10:48,520 --> 00:10:52,000
And since Laravel needs to generate files in that folder

216
00:10:52,000 --> 00:10:54,240
during the php code execution,

217
00:10:54,240 --> 00:10:57,700
for example, log files or cache views,

218
00:10:57,700 --> 00:11:00,273
we need to grant this write access here.

219
00:11:01,240 --> 00:11:05,860
With this change made, we can run docker-compose down

220
00:11:05,860 --> 00:11:08,683
to bring down all running services.

221
00:11:10,030 --> 00:11:11,570
And then we can again, of course, run

222
00:11:11,570 --> 00:11:14,860
docker-compose up with the --build flag

223
00:11:14,860 --> 00:11:18,960
to ensure that this new dockerfile is taken into account

224
00:11:18,960 --> 00:11:20,800
and this command is being executed

225
00:11:20,800 --> 00:11:22,730
and the image is being rebuilt.

226
00:11:22,730 --> 00:11:24,350
And once that is done

227
00:11:24,350 --> 00:11:26,830
and once everything is up and running again,

228
00:11:26,830 --> 00:11:28,740
we should then be able to visit

229
00:11:28,740 --> 00:11:31,090
this running Laravel application.

230
00:11:31,090 --> 00:11:32,800
Now, this is definitely advanced,

231
00:11:32,800 --> 00:11:36,470
and it's all pretty specific to this exact application

232
00:11:36,470 --> 00:11:39,940
and to Laravel needing write access here.

233
00:11:39,940 --> 00:11:42,890
It is something you can all find via Google though

234
00:11:42,890 --> 00:11:45,140
if you, for example, googled this part

235
00:11:45,140 --> 00:11:47,490
of the error message which we got.

236
00:11:47,490 --> 00:11:50,090
If I now reload, we see the starting page again,

237
00:11:50,090 --> 00:11:53,270
and now it's all served just with code

238
00:11:53,270 --> 00:11:55,200
and configuration snapshots

239
00:11:55,200 --> 00:11:58,120
which are copied into our images.

240
00:11:58,120 --> 00:12:01,000
And, again, we don't need this during development,

241
00:12:01,000 --> 00:12:02,720
but if you want an environment

242
00:12:02,720 --> 00:12:05,740
which you cannot just use during development

243
00:12:05,740 --> 00:12:09,950
but which is also having at least some required preparation

244
00:12:09,950 --> 00:12:12,220
for production, for deployment,

245
00:12:12,220 --> 00:12:15,130
then these are changes you wanna make.

246
00:12:15,130 --> 00:12:18,150
With that though, I'll bring back the bind mounts

247
00:12:18,150 --> 00:12:22,540
so that we still can have live code changes being reflected

248
00:12:22,540 --> 00:12:24,410
in our running application.

249
00:12:24,410 --> 00:12:26,330
But now we simply have an application

250
00:12:26,330 --> 00:12:27,870
that's prepared for both,

251
00:12:27,870 --> 00:12:31,050
snapshots being copied into the images when they're built,

252
00:12:31,050 --> 00:12:33,860
and then bind mounts to always have access

253
00:12:33,860 --> 00:12:36,807
to the latest code from inside the container.

254
00:12:37,720 --> 00:12:39,730
Now, one tiny change, by the way,

255
00:12:39,730 --> 00:12:41,900
here on the artisan command,

256
00:12:41,900 --> 00:12:44,350
this all uses the php.dockerfile,

257
00:12:44,350 --> 00:12:48,600
and our extra additions made there are no problem for that.

258
00:12:48,600 --> 00:12:51,820
But we wanna ensure that we now also set the context

259
00:12:51,820 --> 00:12:53,940
to the entire project folder

260
00:12:53,940 --> 00:12:58,940
and change the dockerfile to dockerfiles/php.dockerfile.

261
00:12:59,450 --> 00:13:01,653
Otherwise, running this command would fail.

262
00:13:02,870 --> 00:13:05,000
With that, however, we should be able to run

263
00:13:05,000 --> 00:13:09,380
docker-compose run --rm artisan migrate,

264
00:13:09,380 --> 00:13:12,580
and it should work just fine as before.

265
00:13:12,580 --> 00:13:13,603
Yes, it does.

266
00:13:14,810 --> 00:13:16,650
So now that's the finished setup

267
00:13:16,650 --> 00:13:20,510
with which I wanna end this section now.

268
00:13:20,510 --> 00:13:23,000
Definitely a lot of content covered here,

269
00:13:23,000 --> 00:13:25,220
also a couple of new concepts

270
00:13:25,220 --> 00:13:27,500
or additions to what you learned before,

271
00:13:27,500 --> 00:13:31,460
and definitely all the setup which can be difficult to grasp

272
00:13:31,460 --> 00:13:34,220
if you have no Laravel application

273
00:13:34,220 --> 00:13:36,150
and if you are new to Docker.

274
00:13:36,150 --> 00:13:37,710
My primary goal here

275
00:13:37,710 --> 00:13:40,480
was to show you such a more complex setup

276
00:13:40,480 --> 00:13:42,580
and show you a couple of pain points

277
00:13:42,580 --> 00:13:44,520
you might be facing here.

278
00:13:44,520 --> 00:13:46,087
So if you're thinking,

279
00:13:46,087 --> 00:13:49,090
"Wow, that's something I would have never built on my own,"

280
00:13:49,090 --> 00:13:50,680
that is totally fine here.

281
00:13:50,680 --> 00:13:52,590
We're not done with the course at all.

282
00:13:52,590 --> 00:13:55,420
And especially if you have no Laravel knowledge,

283
00:13:55,420 --> 00:13:57,160
knowing about these building blocks

284
00:13:57,160 --> 00:14:00,900
and how they work together is extra hard.

285
00:14:00,900 --> 00:14:03,550
I still hope you got a lot out of this module

286
00:14:03,550 --> 00:14:06,840
and learned more about Docker and Docker Compose,

287
00:14:06,840 --> 00:14:09,340
how the different parts work together there,

288
00:14:09,340 --> 00:14:11,540
and when you use what.

289
00:14:11,540 --> 00:14:14,040
We'll have more examples throughout this course.

290
00:14:14,040 --> 00:14:15,470
But in the next module,

291
00:14:15,470 --> 00:14:18,773
we'll actually focus on deploying containers.

