1
00:00:02,480 --> 00:00:05,460
Now to come to an end in this course module,

2
00:00:05,460 --> 00:00:08,630
I added a little frontend project here.

3
00:00:08,630 --> 00:00:12,200
So a little application which would run in the browser

4
00:00:12,200 --> 00:00:15,200
in this case, build with React.

5
00:00:15,200 --> 00:00:18,380
And attached, you'll find this new frontend folder,

6
00:00:18,380 --> 00:00:20,340
which you can simply add to your project,

7
00:00:20,340 --> 00:00:22,700
which contains this application.

8
00:00:22,700 --> 00:00:24,470
The idea is simple.

9
00:00:24,470 --> 00:00:26,980
Up to this point, we always used Postman

10
00:00:26,980 --> 00:00:30,010
for testing our deployed application.

11
00:00:30,010 --> 00:00:32,330
And whilst this is nice,

12
00:00:32,330 --> 00:00:34,990
in reality, we would of course typically

13
00:00:34,990 --> 00:00:37,860
have some kind of frontend,

14
00:00:37,860 --> 00:00:40,910
no matter if that's a mobile app or a web app

15
00:00:40,910 --> 00:00:44,460
as in this case with this React application.

16
00:00:44,460 --> 00:00:46,270
Now earlier in the course,

17
00:00:46,270 --> 00:00:49,960
we already saw how we can have multi-container apps

18
00:00:49,960 --> 00:00:53,000
where one of the containers contains a frontend.

19
00:00:53,000 --> 00:00:57,073
We even deployed that in the deployment section.

20
00:00:57,960 --> 00:01:00,020
I wanna come back to it here though,

21
00:01:00,020 --> 00:01:03,030
because now again, we got something deployed.

22
00:01:03,030 --> 00:01:06,500
We have our running Kubernetes application,

23
00:01:06,500 --> 00:01:11,440
or we're using Kubernetes to deploy this multi-container

24
00:01:11,440 --> 00:01:14,473
microservice like application here.

25
00:01:15,440 --> 00:01:19,230
And that's why we can send these requests here, of course.

26
00:01:19,230 --> 00:01:22,960
Now in this frontend folder, in the source folder,

27
00:01:22,960 --> 00:01:26,900
you find the React code for my frontend.

28
00:01:26,900 --> 00:01:30,190
And you don't need to understand React to follow along.

29
00:01:30,190 --> 00:01:32,220
Of course you can dive into the code,

30
00:01:32,220 --> 00:01:35,140
but it's just some very simple dummy code.

31
00:01:35,140 --> 00:01:37,300
No complex application

32
00:01:37,300 --> 00:01:39,590
but there are two important things here.

33
00:01:39,590 --> 00:01:42,000
I'm trying to fetch tasks here

34
00:01:42,000 --> 00:01:45,560
in one code snippet in the App.js file.

35
00:01:45,560 --> 00:01:48,270
And I'm trying to store a new task

36
00:01:48,270 --> 00:01:51,980
in another code snippet in the same file.

37
00:01:51,980 --> 00:01:53,500
So the App.js file

38
00:01:53,500 --> 00:01:56,410
in that source folder in the frontend folder.

39
00:01:56,410 --> 00:01:59,220
And at the moment to concrete URL

40
00:01:59,220 --> 00:02:03,130
to which these requests should be sent is missing.

41
00:02:03,130 --> 00:02:06,150
Now, here in the end, I wanna use that URL

42
00:02:06,150 --> 00:02:11,070
which we also used in Postman, just to also test this.

43
00:02:11,070 --> 00:02:16,070
So of course we can copy that URL that IP and the port here,

44
00:02:16,990 --> 00:02:19,927
which is exposed by minikube, and paste is in here

45
00:02:19,927 --> 00:02:24,927
to send a get request to this URL/tasks in this case here,

46
00:02:27,270 --> 00:02:32,270
and to send a post request in the add task handler function.

47
00:02:35,060 --> 00:02:37,400
Now, if you add it to that

48
00:02:37,400 --> 00:02:39,500
and you need to do that on your own,

49
00:02:39,500 --> 00:02:42,730
because you will have your very own IP address,

50
00:02:42,730 --> 00:02:46,160
you can rebuild this as an image.

51
00:02:46,160 --> 00:02:48,420
And for that I already have a Docker file

52
00:02:48,420 --> 00:02:49,840
in the frontend folder,

53
00:02:49,840 --> 00:02:52,690
and then try to run this as a container.

54
00:02:52,690 --> 00:02:56,660
In this Docker file we have a multistage set up

55
00:02:56,660 --> 00:02:59,380
because there we first of all build the code

56
00:02:59,380 --> 00:03:02,660
and then we set up an nginx web server,

57
00:03:02,660 --> 00:03:06,540
which serves to build files using the configuration,

58
00:03:06,540 --> 00:03:09,580
which is set up in this nginx con file.

59
00:03:09,580 --> 00:03:11,860
And again, this is also something

60
00:03:11,860 --> 00:03:14,810
I already touched on earlier in the course

61
00:03:14,810 --> 00:03:19,110
when we deployed to applications independent of Kubernetes

62
00:03:19,110 --> 00:03:22,100
and indeed here as well up to this point,

63
00:03:22,100 --> 00:03:25,440
we're not using Kubernetes for this frontend.

64
00:03:25,440 --> 00:03:28,930
Instead, you can see the internet frontend folder

65
00:03:28,930 --> 00:03:30,440
in your terminal

66
00:03:30,440 --> 00:03:35,220
and build this frontend project into an image.

67
00:03:35,220 --> 00:03:37,940
And I'll give it my own name.

68
00:03:37,940 --> 00:03:42,940
And here I will already choose academind/kubdemofrontend

69
00:03:43,210 --> 00:03:46,400
even though I have no Docker Hub repository

70
00:03:46,400 --> 00:03:47,700
with that name yet,

71
00:03:47,700 --> 00:03:52,093
but we can add it later and already used this image name.

72
00:03:53,070 --> 00:03:56,300
So this will now build this image

73
00:03:56,300 --> 00:03:59,210
and we'll go through all these steps

74
00:03:59,210 --> 00:04:02,240
in this multistage Docker file.

75
00:04:02,240 --> 00:04:05,980
And once it is built, once this image is built, we can,

76
00:04:05,980 --> 00:04:10,100
of course run a local container based on that image.

77
00:04:10,100 --> 00:04:13,260
And that local container should then be able

78
00:04:13,260 --> 00:04:17,589
to also reach out to our deployed application,

79
00:04:17,589 --> 00:04:20,149
which runs on this Kubernetes Cluster,

80
00:04:20,149 --> 00:04:24,270
because the code, which runs here in this React app,

81
00:04:24,270 --> 00:04:26,100
all this JavaScript code

82
00:04:26,100 --> 00:04:28,500
will run in the browser in the end.

83
00:04:28,500 --> 00:04:31,770
This is not code, which runs inside of the container,

84
00:04:31,770 --> 00:04:35,410
but instead it's code which is served to the browser

85
00:04:35,410 --> 00:04:38,190
and then executes in the browser.

86
00:04:38,190 --> 00:04:41,710
We had that topic earlier in the course already.

87
00:04:41,710 --> 00:04:44,790
That's why we can use this URL like this.

88
00:04:44,790 --> 00:04:46,410
If we can use it in Postman,

89
00:04:46,410 --> 00:04:48,130
and if we could use it in the browser,

90
00:04:48,130 --> 00:04:50,150
it will also work in does React code

91
00:04:50,150 --> 00:04:52,590
because this code will just run in the browser.

92
00:04:52,590 --> 00:04:54,980
This will not run inside of a container

93
00:04:54,980 --> 00:04:57,780
and therefore this will not be interpreted

94
00:04:57,780 --> 00:05:01,490
as some kind of container internal address

95
00:05:01,490 --> 00:05:03,253
or anything like that.

96
00:05:04,220 --> 00:05:05,500
So long story short,

97
00:05:05,500 --> 00:05:07,900
this code will eventually run in the browser.

98
00:05:07,900 --> 00:05:11,950
So our minikube server should be reachable

99
00:05:11,950 --> 00:05:13,440
with that IP address.

100
00:05:13,440 --> 00:05:17,950
And therefore, once that built here is done,

101
00:05:17,950 --> 00:05:19,640
once our images built,

102
00:05:19,640 --> 00:05:23,410
we should be able to run a container locally on our system

103
00:05:23,410 --> 00:05:26,580
and test this frontend application.

104
00:05:26,580 --> 00:05:28,940
So for this, we can run Docker run

105
00:05:28,940 --> 00:05:31,540
and then use that image name we just assigned,

106
00:05:31,540 --> 00:05:34,610
academind/kub-demo-frontend

107
00:05:35,630 --> 00:05:39,420
make sure to publish port 80 on port 80

108
00:05:39,420 --> 00:05:42,950
because this frontend app will listen on port 80,

109
00:05:42,950 --> 00:05:46,630
and that is the port exposed here.

110
00:05:46,630 --> 00:05:50,350
And it will also add --RM to remove the container

111
00:05:50,350 --> 00:05:54,733
if it's stopped and add -D to start it in detached mode.

112
00:05:55,690 --> 00:05:58,040
And again, just to emphasize it,

113
00:05:58,040 --> 00:06:01,020
of course, this has nothing to do with Kubernetes here

114
00:06:01,020 --> 00:06:03,080
we're using good old Docker

115
00:06:03,080 --> 00:06:06,260
to run a container on our local host machine,

116
00:06:06,260 --> 00:06:08,310
not in a Kubernetes Cluster,

117
00:06:08,310 --> 00:06:11,180
just on our local host machine for the moment

118
00:06:11,180 --> 00:06:14,600
to then connect to that cluster though.

119
00:06:14,600 --> 00:06:17,520
So if I hit enter, this container starts up

120
00:06:17,520 --> 00:06:20,930
and thereafter if you enter local host in your browser,

121
00:06:20,930 --> 00:06:22,873
this application should be loaded.

122
00:06:23,720 --> 00:06:27,760
Now you will see that no tasks are fetched though

123
00:06:27,760 --> 00:06:30,510
even if you click the fetch tasks button,

124
00:06:30,510 --> 00:06:33,850
because if you open up the developer tools in the browser,

125
00:06:33,850 --> 00:06:37,650
you will see that we have a CORs error here,

126
00:06:37,650 --> 00:06:40,260
and this is actually not a bug with Kubernetes

127
00:06:40,260 --> 00:06:42,040
or with anything like that.

128
00:06:42,040 --> 00:06:43,730
But instead our backend,

129
00:06:43,730 --> 00:06:45,740
which we deployed with Kubernetes,

130
00:06:45,740 --> 00:06:50,740
doesn't have the appropriate code to allow the requests

131
00:06:51,030 --> 00:06:52,873
to the tasks application.

132
00:06:54,120 --> 00:06:56,690
For Postman this wasn't a problem

133
00:06:56,690 --> 00:07:01,480
because this idea of cross origin resource sharing

134
00:07:01,480 --> 00:07:05,070
does not matter to Postman but for browsers it does.

135
00:07:05,070 --> 00:07:08,570
And if CORs errors and cross original resource sharing,

136
00:07:08,570 --> 00:07:10,440
doesn't tell you anything

137
00:07:10,440 --> 00:07:13,690
attached you find a resource on that,

138
00:07:13,690 --> 00:07:16,233
which should help you understand this error.

139
00:07:17,153 --> 00:07:21,850
The simple solution is that we need to update our code in

140
00:07:21,850 --> 00:07:26,430
the tasks API to make sure that some extra headers are set,

141
00:07:26,430 --> 00:07:27,990
which then tell the browser

142
00:07:27,990 --> 00:07:31,100
that reaching out to that API is okay.

143
00:07:31,100 --> 00:07:32,930
Now the code, which you need to add

144
00:07:32,930 --> 00:07:36,910
to your tasks app JS file can also be found attached.

145
00:07:36,910 --> 00:07:41,200
T be precise, you'll simply find a new tasks app JS file,

146
00:07:41,200 --> 00:07:43,770
which you can use to replace yours with it.

147
00:07:43,770 --> 00:07:46,000
This code block is new,

148
00:07:46,000 --> 00:07:48,500
and this just sets the appropriate headers,

149
00:07:48,500 --> 00:07:50,620
which ensures that browsers

150
00:07:50,620 --> 00:07:52,830
and application running in the browsers

151
00:07:52,830 --> 00:07:56,453
can indeed communicate with that API without problems.

152
00:07:57,300 --> 00:08:02,170
I'm not adding this to the user's API simply

153
00:08:02,170 --> 00:08:04,870
because this frontend, this dummy frontend,

154
00:08:04,870 --> 00:08:06,370
which I'm providing to you

155
00:08:06,370 --> 00:08:08,930
doesn't try to talk to that API.

156
00:08:08,930 --> 00:08:09,763
If it would,

157
00:08:09,763 --> 00:08:12,963
we would need to add these headers there as well.

158
00:08:14,160 --> 00:08:18,000
With that however, we updated our tasks API source code,

159
00:08:18,000 --> 00:08:21,710
and that of course means that we need to redeploy it.

160
00:08:21,710 --> 00:08:26,490
So, first of all, we should go into the tasks API folder

161
00:08:26,490 --> 00:08:28,530
and build our image again,

162
00:08:28,530 --> 00:08:33,320
the academind/kub-demo-tasks image,

163
00:08:33,320 --> 00:08:35,780
and then we need to push it again, of course,

164
00:08:35,780 --> 00:08:39,530
so that the latest and greatest source code

165
00:08:39,530 --> 00:08:42,380
can be found on Docker Hub.

166
00:08:42,380 --> 00:08:47,380
So I want to push academind/kub-demo-tasks here,

167
00:08:47,530 --> 00:08:48,850
and once it is pushed,

168
00:08:48,850 --> 00:08:51,830
we of course need to make sure that this latest code

169
00:08:51,830 --> 00:08:55,310
is also being deployed at Kubernetes.

170
00:08:55,310 --> 00:08:59,153
And since I didn't change any of my deployment YAML files,

171
00:09:00,952 --> 00:09:02,680
I can't just apply a new configuration,

172
00:09:02,680 --> 00:09:05,510
instead I will delete an existing deployment

173
00:09:05,510 --> 00:09:08,460
and then apply the same deployment again,

174
00:09:08,460 --> 00:09:11,910
which will then lead to the new image being pulled.

175
00:09:11,910 --> 00:09:14,823
So let's wait for it as push process to finish.

176
00:09:16,060 --> 00:09:18,220
And now that it finished,

177
00:09:18,220 --> 00:09:21,090
we can go back into the Kubernetes folder

178
00:09:21,090 --> 00:09:24,360
and run kube + Control, delete-F tasksdeployment.yaml.

179
00:09:28,750 --> 00:09:29,900
Then thereafter,

180
00:09:29,900 --> 00:09:34,900
run kube + Control apply -F tasks deployment.yaml,

181
00:09:35,110 --> 00:09:37,810
and this will then recreate this deployment,

182
00:09:37,810 --> 00:09:41,100
but now use the latest source code.

183
00:09:41,100 --> 00:09:43,880
So eventually that container will be created

184
00:09:43,880 --> 00:09:47,290
and our pod will be up and running again.

185
00:09:47,290 --> 00:09:51,520
Here we go, the new container is up and running.

186
00:09:51,520 --> 00:09:55,070
And with that, the latest code is active there

187
00:09:55,070 --> 00:09:59,370
so now if we reload this React application in the browser

188
00:09:59,370 --> 00:10:01,420
you will see that it crashes.

189
00:10:01,420 --> 00:10:03,460
And if you open the developer tools again,

190
00:10:03,460 --> 00:10:05,060
you see that this happens

191
00:10:05,060 --> 00:10:07,513
because we got the unauthorized error.

192
00:10:08,490 --> 00:10:10,330
This shouldn't be a surprise.

193
00:10:10,330 --> 00:10:12,260
With postman, we did have

194
00:10:12,260 --> 00:10:15,530
to add our authorization header here

195
00:10:15,530 --> 00:10:17,580
with this dummy value in order

196
00:10:17,580 --> 00:10:20,510
to successfully fetch our tasks.

197
00:10:20,510 --> 00:10:23,290
Here by the way it fails because I redeployed it

198
00:10:23,290 --> 00:10:24,770
and therefore all tasks,

199
00:10:24,770 --> 00:10:27,970
which were stored in the past were erased.

200
00:10:27,970 --> 00:10:31,430
But if I post a new task, I can fetch it again,

201
00:10:31,430 --> 00:10:35,717
but we need this authorization header and the frontend,

202
00:10:35,717 --> 00:10:38,790
the React application here, which runs in the browser,

203
00:10:38,790 --> 00:10:40,673
of course will be no exception.

204
00:10:41,540 --> 00:10:45,370
Now to add this header, we can go to this source code,

205
00:10:45,370 --> 00:10:49,080
the React source code and there this fetch task function

206
00:10:49,080 --> 00:10:52,250
in the end and add a second argument here.

207
00:10:52,250 --> 00:10:54,920
So simply a comma and then curly braces,

208
00:10:54,920 --> 00:10:58,660
opening and closing, and add a headers option,

209
00:10:58,660 --> 00:11:02,080
then a colon and then another object

210
00:11:02,080 --> 00:11:05,130
by using opening and closing curly braces.

211
00:11:05,130 --> 00:11:07,710
And then between single quotes

212
00:11:07,710 --> 00:11:11,940
add the authorization header,

213
00:11:11,940 --> 00:11:14,460
and then a colon and the value for it is header,

214
00:11:14,460 --> 00:11:17,423
which should be bearer wide space ABC.

215
00:11:18,460 --> 00:11:21,710
So this needs to be added to this request,

216
00:11:21,710 --> 00:11:24,640
which is sent with help of this fetch function

217
00:11:24,640 --> 00:11:28,560
to provide this header to debts tasks API

218
00:11:28,560 --> 00:11:30,193
when the request is sent.

219
00:11:31,780 --> 00:11:34,520
Now since I changed the React source code,

220
00:11:34,520 --> 00:11:37,630
we should of course, go into the frontend folder again

221
00:11:37,630 --> 00:11:39,230
and build the image again.

222
00:11:39,230 --> 00:11:44,230
So build this academind/kub-demo-frontend image again

223
00:11:44,550 --> 00:11:46,640
with the Docker build command

224
00:11:46,640 --> 00:11:49,570
so that the latest source code is picked up

225
00:11:49,570 --> 00:11:52,130
and is rebuilt as an application.

226
00:11:52,130 --> 00:11:56,260
And once that happened, we can rerun our container.

227
00:11:56,260 --> 00:11:58,100
So therefore, first of all,

228
00:11:58,100 --> 00:12:02,270
let's stop that running container with Docker stop

229
00:12:02,270 --> 00:12:05,060
and by using the name, which was automatically assigned

230
00:12:06,050 --> 00:12:08,453
so that we have no running container anymore.

231
00:12:09,450 --> 00:12:14,310
And once that happened, we can run our container again,

232
00:12:14,310 --> 00:12:15,480
based on that image,

233
00:12:15,480 --> 00:12:20,480
which we just rebuilt, publish our port 80,

234
00:12:20,650 --> 00:12:25,053
remove it when it stops and run it in detached mode.

235
00:12:26,240 --> 00:12:30,930
And if we now run this again, we can reload local host,

236
00:12:30,930 --> 00:12:34,465
and we now should see this one task being fetched.

237
00:12:34,465 --> 00:12:38,850
And if I create a new task, this should also work.

238
00:12:38,850 --> 00:12:42,060
If I click add task and click fetch tasks again,

239
00:12:42,060 --> 00:12:44,510
you see that task is all the fetched.

240
00:12:44,510 --> 00:12:47,120
Now this is all not kube fancier

241
00:12:47,120 --> 00:12:50,080
because it's just a basic demo application

242
00:12:50,080 --> 00:12:52,820
without any advanced functionality.

243
00:12:52,820 --> 00:12:56,500
For example, we also have no error handling built in there.

244
00:12:56,500 --> 00:12:58,360
This is all missing.

245
00:12:58,360 --> 00:13:02,150
It's really just there to show you that a frontend,

246
00:13:02,150 --> 00:13:05,160
which is not Postman is also able to talk

247
00:13:05,160 --> 00:13:08,163
to this Kubernetes managed backend.

248
00:13:09,230 --> 00:13:11,430
However, now is the thing which

249
00:13:11,430 --> 00:13:13,930
I actually want to dive into in this module

250
00:13:13,930 --> 00:13:16,030
to conclude this module.

251
00:13:16,030 --> 00:13:19,010
What if we want to host this frontend

252
00:13:19,010 --> 00:13:21,290
in our cluster as well.

253
00:13:21,290 --> 00:13:24,570
So of course the code should still execute in the browser,

254
00:13:24,570 --> 00:13:27,080
but it shouldn't be served by that cluster

255
00:13:27,080 --> 00:13:30,470
because at the moment we had to run our container locally

256
00:13:30,470 --> 00:13:32,420
here with Docker run.

257
00:13:32,420 --> 00:13:35,610
And whilst we, of course can do that during development

258
00:13:35,610 --> 00:13:38,200
this is not something we do when we want

259
00:13:38,200 --> 00:13:40,310
to serve this to our end users.

260
00:13:40,310 --> 00:13:44,580
There, it should be on some server may be on the same server

261
00:13:44,580 --> 00:13:48,283
or in the same cluster as all our backend services.

262
00:13:49,140 --> 00:13:51,360
So that's what we're going to have a look at next,

263
00:13:51,360 --> 00:13:56,360
how we could deploy this frontend application to Kubernetes.

264
00:13:56,490 --> 00:13:58,330
For that, I will first of all stop

265
00:13:58,330 --> 00:14:01,990
this container with Docker stop.

266
00:14:01,990 --> 00:14:03,520
And then in the next lecture,

267
00:14:03,520 --> 00:14:05,793
we're going to dive into a deploy that.

