1
00:00:02,050 --> 00:00:04,350
So hard coding the address here

2
00:00:04,350 --> 00:00:06,920
into our front end code is possible

3
00:00:06,920 --> 00:00:09,880
and not really that dramatic.

4
00:00:09,880 --> 00:00:12,800
But we can actually avoid doing that.

5
00:00:12,800 --> 00:00:16,120
By using a trick, which we could have used before too,

6
00:00:16,120 --> 00:00:18,660
but which I now finally wanna show you.

7
00:00:18,660 --> 00:00:23,190
We can use a so-called reverse proxy.

8
00:00:23,190 --> 00:00:25,290
And that's a very fancy term

9
00:00:25,290 --> 00:00:28,720
for one simple thing which we wanna do.

10
00:00:28,720 --> 00:00:32,570
We wanna send the request to ourselves.

11
00:00:32,570 --> 00:00:35,190
And with that I mean to the server,

12
00:00:35,190 --> 00:00:37,930
which serves this frontend application.

13
00:00:37,930 --> 00:00:41,040
So in this case to this nginx server,

14
00:00:41,040 --> 00:00:44,650
which we set up and start in our Dockerfile here

15
00:00:44,650 --> 00:00:45,803
for this frontend.

16
00:00:46,950 --> 00:00:49,780
We wanna send the request to ourself.

17
00:00:49,780 --> 00:00:53,290
Now typically when a request reaches that server,

18
00:00:53,290 --> 00:00:55,683
this frontend application is served.

19
00:00:56,530 --> 00:00:58,180
But we can actually dive

20
00:00:58,180 --> 00:01:00,700
into the configuration of this server,

21
00:01:00,700 --> 00:01:04,330
to generally serve our frontend

22
00:01:04,330 --> 00:01:08,340
but to then also redirect requests to some other host

23
00:01:09,360 --> 00:01:13,260
some other domain if they have a certain structure.

24
00:01:13,260 --> 00:01:16,420
If they target a specific path for example.

25
00:01:16,420 --> 00:01:20,033
And that's this concept which is called reverse proxy.

26
00:01:21,270 --> 00:01:25,350
You can enable it by going to your nginx.conf file

27
00:01:25,350 --> 00:01:27,230
in the conf folder,

28
00:01:27,230 --> 00:01:31,020
and then between listen 80 and location slash,

29
00:01:31,020 --> 00:01:35,860
add location slash API for example.

30
00:01:35,860 --> 00:01:40,560
And this is generally up to you, this slash API part.

31
00:01:40,560 --> 00:01:43,100
This simply means that you now wanna set up

32
00:01:43,100 --> 00:01:46,790
a dedicated configuration for requests

33
00:01:46,790 --> 00:01:51,330
reaching this nginx server where the path,

34
00:01:51,330 --> 00:01:55,260
so the part after the domain or after the IP address,

35
00:01:55,260 --> 00:01:57,423
starts with slash API.

36
00:01:58,490 --> 00:02:00,210
If it starts with anything else,

37
00:02:00,210 --> 00:02:02,620
this configuration will kick in

38
00:02:02,620 --> 00:02:06,650
and will in the end serve your build react application.

39
00:02:06,650 --> 00:02:08,583
So this frontend application.

40
00:02:09,530 --> 00:02:12,780
But if a request should target slash API

41
00:02:12,780 --> 00:02:16,010
or slash API slash something else,

42
00:02:16,010 --> 00:02:19,320
then this configuration will kick in.

43
00:02:19,320 --> 00:02:22,070
And at the moment of course this does nothing.

44
00:02:22,070 --> 00:02:24,323
But that's the part which we can change now.

45
00:02:25,270 --> 00:02:28,190
In here, you can use a special instruction

46
00:02:28,190 --> 00:02:30,270
which nginx understands.

47
00:02:30,270 --> 00:02:35,270
And that's the proxy underscore pass instruction.

48
00:02:35,400 --> 00:02:40,400
This tells nginx that the request to slash API,

49
00:02:41,580 --> 00:02:46,030
so this server slash API should be forwarded

50
00:02:46,030 --> 00:02:47,623
to some other address.

51
00:02:48,750 --> 00:02:52,720
And now here we could grab our URL here

52
00:02:53,650 --> 00:02:57,350
which points at this deployed task service,

53
00:02:57,350 --> 00:03:02,350
and put that here after the proxy path instruction.

54
00:03:03,550 --> 00:03:07,330
Which means requests to this server slash API,

55
00:03:07,330 --> 00:03:09,240
will actually be forwarded

56
00:03:09,240 --> 00:03:11,053
to this address instead.

57
00:03:11,890 --> 00:03:15,590
So they will in the end not be handled by this nginx server,

58
00:03:15,590 --> 00:03:18,893
but by this other server to which they are passed on.

59
00:03:19,800 --> 00:03:22,840
Side note, add a semi colon after this line

60
00:03:22,840 --> 00:03:25,203
to a widen error later which I will face.

61
00:03:26,140 --> 00:03:27,910
Now why is this helpful?

62
00:03:27,910 --> 00:03:30,000
Why could this be interesting?

63
00:03:30,000 --> 00:03:31,696
Well if you save this file now,

64
00:03:31,696 --> 00:03:34,370
you can go to your app.js file

65
00:03:34,370 --> 00:03:37,920
and get rid of the URL in your JavaScript code here.

66
00:03:37,920 --> 00:03:40,110
And instead just send it to the server

67
00:03:40,110 --> 00:03:45,093
you are already running on slash API and then slash tasks.

68
00:03:46,160 --> 00:03:48,340
This here will tell the browser

69
00:03:48,340 --> 00:03:49,840
that it will send the request

70
00:03:49,840 --> 00:03:53,520
to the same server that served this application,

71
00:03:53,520 --> 00:03:56,730
but then they are to slash API slash tasks.

72
00:03:56,730 --> 00:03:59,570
And since we started with slash API here,

73
00:03:59,570 --> 00:04:01,870
it in the end by our server,

74
00:04:01,870 --> 00:04:04,550
will be forwarded to this IP address

75
00:04:04,550 --> 00:04:08,523
which turns out to be the tasks service in this deployment.

76
00:04:09,780 --> 00:04:10,890
And of course I wanna do that

77
00:04:10,890 --> 00:04:13,150
not just for this post request,

78
00:04:13,150 --> 00:04:15,808
but also here in fetchTasks.

79
00:04:15,808 --> 00:04:19,279
Send this to slash API slash tasks.

80
00:04:19,279 --> 00:04:21,813
That leading slash here is important by the way.

81
00:04:22,900 --> 00:04:26,440
So with that we're using this reverse proxy concept.

82
00:04:26,440 --> 00:04:29,300
We are not at the final stage yet.

83
00:04:29,300 --> 00:04:30,930
I wanted to omit this even more

84
00:04:30,930 --> 00:04:33,170
but this is an important first step.

85
00:04:33,170 --> 00:04:35,550
Let's now test whether it works.

86
00:04:35,550 --> 00:04:37,170
And for that,

87
00:04:37,170 --> 00:04:41,033
make sure you go into that frontend folder here,

88
00:04:42,160 --> 00:04:44,420
and then rebuild your image

89
00:04:44,420 --> 00:04:48,770
because you changed the configuration and the source code.

90
00:04:48,770 --> 00:04:52,120
So make sure you run this Docker build dash t

91
00:04:52,120 --> 00:04:56,020
and then your repository image name command again

92
00:04:56,020 --> 00:04:58,600
to update this image.

93
00:04:58,600 --> 00:05:02,060
And thereafter of course also push the updated image

94
00:05:02,060 --> 00:05:04,440
to Docker hub so that Kubernetes

95
00:05:04,440 --> 00:05:07,140
is able to use that latest image.

96
00:05:07,140 --> 00:05:08,900
So once it was built,

97
00:05:08,900 --> 00:05:12,263
of course you also need to push this image here,

98
00:05:13,100 --> 00:05:16,563
like this to Docker hub.

99
00:05:17,680 --> 00:05:20,130
And once this pushing is successful,

100
00:05:20,130 --> 00:05:22,660
we wanna delete the frontend deployment,

101
00:05:22,660 --> 00:05:26,350
and reapply it to fetch that latest code.

102
00:05:26,350 --> 00:05:30,470
And then we wanna see if the application still works.

103
00:05:30,470 --> 00:05:33,760
So let's wait for the push process to finish.

104
00:05:33,760 --> 00:05:36,120
And now that it is finished,

105
00:05:36,120 --> 00:05:38,000
I will go out of this folder

106
00:05:38,000 --> 00:05:40,310
into the Kubernetes folder

107
00:05:40,310 --> 00:05:43,750
and run Kubectl control delete dash f

108
00:05:43,750 --> 00:05:47,173
frontend dash deployment.yaml.

109
00:05:48,440 --> 00:05:51,270
And then again, run Kubectl control apply dash f

110
00:05:51,270 --> 00:05:55,150
frontend dash deployment.yaml,

111
00:05:55,150 --> 00:05:58,143
to reapply it and fetch the latest source code.

112
00:06:00,010 --> 00:06:04,730
So now the containers are again recreated here.

113
00:06:04,730 --> 00:06:08,460
And actually here it crashes and fails to start,

114
00:06:08,460 --> 00:06:12,253
simply because I forgot a semi colon after this here.

115
00:06:13,690 --> 00:06:17,130
And with that semi colon added it will work though.

116
00:06:17,130 --> 00:06:21,280
So I will quickly just rebuild everything therefore

117
00:06:21,280 --> 00:06:23,833
and push it again to apply these changes.

118
00:06:25,210 --> 00:06:28,960
So build DMH again to pick up that latest configuration

119
00:06:28,960 --> 00:06:30,993
with the added semi-colon here.

120
00:06:32,010 --> 00:06:34,410
And once that finished,

121
00:06:34,410 --> 00:06:37,640
I push the updated code to Docker hub of course,

122
00:06:37,640 --> 00:06:40,120
push the updated image I mean,

123
00:06:40,120 --> 00:06:41,930
and once that is pushed

124
00:06:41,930 --> 00:06:46,120
I will delete the deployment which fails to start

125
00:06:46,120 --> 00:06:48,313
and of course redeploy.

126
00:06:49,300 --> 00:06:53,070
So go back into that Kubernetes folder,

127
00:06:53,070 --> 00:06:55,930
run the Kubectl control delete command again

128
00:06:55,930 --> 00:06:59,110
and run the Kubectl control apply command again,

129
00:06:59,110 --> 00:07:01,520
and now it should be deployed successfully.

130
00:07:01,520 --> 00:07:03,710
So now if I get my pods,

131
00:07:03,710 --> 00:07:06,680
this gets created and eventually

132
00:07:06,680 --> 00:07:09,480
it now should start up successfully.

133
00:07:09,480 --> 00:07:11,540
And if you now visit the same IP

134
00:07:11,540 --> 00:07:13,610
from before again and reload,

135
00:07:13,610 --> 00:07:17,230
it'll work again, at least almost.

136
00:07:17,230 --> 00:07:18,973
Where are the tasks?

137
00:07:20,130 --> 00:07:23,820
Well if you open your developer tools, you'll see an error.

138
00:07:23,820 --> 00:07:28,820
That in the end it fails to find this URL.

139
00:07:28,907 --> 00:07:32,510
And the reason for that will be (indistinct) simple.

140
00:07:32,510 --> 00:07:35,810
If I send the request to API slash tasks,

141
00:07:35,810 --> 00:07:37,670
it fails to find that.

142
00:07:37,670 --> 00:07:39,480
And of course it should find that right

143
00:07:39,480 --> 00:07:43,200
because an nginx.config we are redirecting requests

144
00:07:43,200 --> 00:07:45,883
that start with slash API.

145
00:07:47,350 --> 00:07:51,000
Well, yes, but where are we redirecting them to?

146
00:07:51,000 --> 00:07:53,540
We are redirecting them to this IP.

147
00:07:53,540 --> 00:07:56,603
And what could be the problem with that IP now?

148
00:07:57,830 --> 00:08:02,830
This is an IP which we can use on our local machine

149
00:08:03,030 --> 00:08:06,870
to access this cluster which is spun up

150
00:08:06,870 --> 00:08:09,380
and managed by mini cube.

151
00:08:09,380 --> 00:08:12,060
But this configuration indeed

152
00:08:12,060 --> 00:08:15,750
will not be executed on our local machine.

153
00:08:15,750 --> 00:08:17,810
Instead this configuration,

154
00:08:17,810 --> 00:08:20,060
and that's not really the key thing.

155
00:08:20,060 --> 00:08:25,060
This configuration will execute on the server so to say.

156
00:08:26,050 --> 00:08:28,820
It will run inside of the container.

157
00:08:28,820 --> 00:08:31,720
And that's a key difference to our react code

158
00:08:31,720 --> 00:08:35,600
to this JavaScript code in the app.js file for example.

159
00:08:35,600 --> 00:08:38,909
This runs in the browser and therefore technically

160
00:08:38,909 --> 00:08:42,273
outside of the cluster on our local host machine.

161
00:08:43,390 --> 00:08:45,960
The code into configuration however,

162
00:08:45,960 --> 00:08:48,330
is parsed when the server starts

163
00:08:48,330 --> 00:08:52,860
and that happens on the cluster inside of the cluster.

164
00:08:52,860 --> 00:08:56,910
So here, and that's why I'm this reverse proxy.

165
00:08:56,910 --> 00:09:01,540
We can use cluster internal IP addresses.

166
00:09:01,540 --> 00:09:04,630
And we can of course for example also

167
00:09:04,630 --> 00:09:08,410
use our automatically generated domain names.

168
00:09:08,410 --> 00:09:10,760
And that's the cool thing here.

169
00:09:10,760 --> 00:09:15,140
We can use task service dot default for example,

170
00:09:15,140 --> 00:09:16,660
as a domain name.

171
00:09:16,660 --> 00:09:19,480
Because as I explained a couple of lectures ago,

172
00:09:19,480 --> 00:09:23,650
these domain names are generated automatically

173
00:09:23,650 --> 00:09:27,390
for the services registered in your cluster.

174
00:09:27,390 --> 00:09:30,160
And since this code now runs on the cluster,

175
00:09:30,160 --> 00:09:33,350
this can be evaluated and resolved

176
00:09:33,350 --> 00:09:38,350
by Kubernetes and it will actually find our tasks service

177
00:09:38,350 --> 00:09:40,600
when we use this domain.

178
00:09:40,600 --> 00:09:43,810
And that's the cool thing about the reverse proxy

179
00:09:43,810 --> 00:09:47,770
even though our code executes on inside of the browser,

180
00:09:47,770 --> 00:09:50,260
and therefore would normally not run

181
00:09:50,260 --> 00:09:51,890
inside of the container.

182
00:09:51,890 --> 00:09:53,870
With the reverse proxy concept

183
00:09:53,870 --> 00:09:56,160
we can kind of work around that,

184
00:09:56,160 --> 00:09:59,430
and still have code that runs inside of the container

185
00:09:59,430 --> 00:10:02,830
and therefore we can take advantage of things like

186
00:10:02,830 --> 00:10:05,440
the automatic assignment of domain names

187
00:10:05,440 --> 00:10:10,003
and the translation to cluster managed IP addresses.

188
00:10:10,860 --> 00:10:14,340
And I wanna emphasize that this is not some dirty trick,

189
00:10:14,340 --> 00:10:17,660
instead this a quite normal approach

190
00:10:17,660 --> 00:10:19,800
to make something like this work.

191
00:10:19,800 --> 00:10:23,280
And we could have used it before in this course as well

192
00:10:23,280 --> 00:10:24,817
when we deployed to AWS.

193
00:10:25,730 --> 00:10:28,050
It has nothing to do with Kubernetes,

194
00:10:28,050 --> 00:10:31,443
but of course therefore it also works with Kubernetes.

195
00:10:32,680 --> 00:10:36,200
So if we change our configuration like this,

196
00:10:36,200 --> 00:10:40,210
now we should be able to send this request successfully.

197
00:10:40,210 --> 00:10:42,620
Now besides adding this domain name here

198
00:10:42,620 --> 00:10:45,000
there are two other things we gotta do though.

199
00:10:45,000 --> 00:10:47,640
For one, you need a trailing slash here,

200
00:10:47,640 --> 00:10:52,640
and you need a trailing slash here after API.

201
00:10:52,690 --> 00:10:54,170
This might not look like much

202
00:10:54,170 --> 00:10:57,260
but this ensures that the correct path

203
00:10:57,260 --> 00:11:01,410
is later forwarded to your tasks service.

204
00:11:01,410 --> 00:11:04,000
Now one last thing we should do here,

205
00:11:04,000 --> 00:11:07,500
we have to keep in mind that our tasks service

206
00:11:07,500 --> 00:11:11,060
in the end listens on port 8,000.

207
00:11:11,060 --> 00:11:14,490
That's also what we defined in the yaml file

208
00:11:14,490 --> 00:11:17,120
for the tasks service.

209
00:11:17,120 --> 00:11:19,240
It exposes port 8,000

210
00:11:19,240 --> 00:11:22,750
and therefore in this nginx.conf file,

211
00:11:22,750 --> 00:11:26,540
we wanna forward to tasks dash service dot default

212
00:11:26,540 --> 00:11:30,810
colon 8,000 to forward it to this correct port

213
00:11:30,810 --> 00:11:32,480
and not to port 80

214
00:11:32,480 --> 00:11:35,510
which would not be able to handle incoming requests

215
00:11:35,510 --> 00:11:39,313
because it's not the port exposed by the tasks service.

216
00:11:40,530 --> 00:11:43,060
With (indistinct) however, everything will work.

217
00:11:43,060 --> 00:11:47,030
And now we just have to go back into the frontend folder,

218
00:11:47,030 --> 00:11:50,570
and rebuild this image to pick up that latest code

219
00:11:50,570 --> 00:11:52,920
and to push it to Docker hub again.

220
00:11:52,920 --> 00:11:55,140
So run the Docker build command again,

221
00:11:55,140 --> 00:11:57,730
to rebuild this frontend image.

222
00:11:57,730 --> 00:12:00,860
And once it is rebuilt, we'll push it again

223
00:12:00,860 --> 00:12:04,140
so that we can then delete and recreate the deployment

224
00:12:04,140 --> 00:12:06,443
which will pick up that latest image.

225
00:12:07,440 --> 00:12:11,173
So Docker push for the updated image is the next step.

226
00:12:12,920 --> 00:12:16,603
And let's wait for that push process to finish.

227
00:12:17,490 --> 00:12:20,910
And now once that was pushed successfully,

228
00:12:20,910 --> 00:12:23,163
we go back into the Kubernetes folder,

229
00:12:24,120 --> 00:12:28,200
and we Kubectl control delete the old frontends deployment

230
00:12:28,200 --> 00:12:31,960
and then kubectl control apply the same deployment again

231
00:12:31,960 --> 00:12:35,453
but now it will automatically pick up that latest image.

232
00:12:37,070 --> 00:12:39,260
And if you now reload this IP

233
00:12:39,260 --> 00:12:41,440
which serves the react application,

234
00:12:41,440 --> 00:12:43,120
which hasn't changed at all by the way.

235
00:12:43,120 --> 00:12:45,180
This IP address is always the same

236
00:12:45,180 --> 00:12:48,090
because we never removed the frontend service.

237
00:12:48,090 --> 00:12:50,330
You should see your tasks again

238
00:12:50,330 --> 00:12:53,800
and you should be able to add a fourth task

239
00:12:53,800 --> 00:12:56,260
which is maybe learn Docker in-depth.

240
00:12:56,260 --> 00:12:59,710
If you now fetch the tasks again, that also is there.

241
00:12:59,710 --> 00:13:01,670
You can reload and it's still there.

242
00:13:01,670 --> 00:13:03,230
And that all works

243
00:13:03,230 --> 00:13:07,270
now thanks to this reverse proxy concept.

244
00:13:07,270 --> 00:13:09,090
And I wanted to show this to you

245
00:13:09,090 --> 00:13:11,750
because it's a nice way of leveraging,

246
00:13:11,750 --> 00:13:15,550
the automatically generated domain names.

247
00:13:15,550 --> 00:13:19,480
And it ensures that you never have to manually fetch

248
00:13:19,480 --> 00:13:23,160
and enter addresses of your backend services,

249
00:13:23,160 --> 00:13:25,550
into your frontend code here.

250
00:13:25,550 --> 00:13:28,700
You can use this reverse proxy concept instead,

251
00:13:28,700 --> 00:13:32,460
to let Kubernetes give you the IP of that tasks service

252
00:13:32,460 --> 00:13:36,400
and your code does never contain that IP.

253
00:13:36,400 --> 00:13:38,800
Which makes your code more flexible

254
00:13:38,800 --> 00:13:41,580
and allows you to focus on writing your code

255
00:13:41,580 --> 00:13:44,840
and setting up that Kubernetes configuration.

256
00:13:44,840 --> 00:13:46,690
So this is a powerful pattern,

257
00:13:46,690 --> 00:13:49,790
which does not just work with Kubernetes,

258
00:13:49,790 --> 00:13:52,200
but which also works with Kubernetes.

259
00:13:52,200 --> 00:13:54,200
And therefore it's definitely something

260
00:13:54,200 --> 00:13:55,393
which is worth knowing.

