1
00:00:02,090 --> 00:00:04,740
Before we ensure that data persists

2
00:00:04,740 --> 00:00:08,240
and so on, let's continue with the backend,

3
00:00:08,240 --> 00:00:10,970
let's also dockerize that.

4
00:00:10,970 --> 00:00:12,600
For this I'll go to the terminal

5
00:00:12,600 --> 00:00:14,900
where I have my node server running,

6
00:00:14,900 --> 00:00:17,360
and I will again quit it with control C,

7
00:00:17,360 --> 00:00:20,453
and now I want to put this into a container.

8
00:00:21,510 --> 00:00:24,920
For this, we need to write our own Docker file,

9
00:00:24,920 --> 00:00:28,630
to build our own image for this project.

10
00:00:28,630 --> 00:00:30,800
We didn't need to do this for MongoDB,

11
00:00:30,800 --> 00:00:32,980
because we already have this official image,

12
00:00:32,980 --> 00:00:34,600
which starts database,

13
00:00:34,600 --> 00:00:35,433
but of course,

14
00:00:35,433 --> 00:00:38,763
there's no official image for our own custom application.

15
00:00:39,640 --> 00:00:41,140
Now, here we start with from,

16
00:00:41,140 --> 00:00:43,200
and we use the node as a base image.

17
00:00:43,200 --> 00:00:47,120
We could also add the 14 tag to use version 14

18
00:00:47,120 --> 00:00:49,533
or node like this to use the latest version.

19
00:00:51,290 --> 00:00:53,940
Next, I will set the working directory

20
00:00:53,940 --> 00:00:55,740
to a directory of my choice,

21
00:00:55,740 --> 00:00:57,210
and I will go with app,

22
00:00:57,210 --> 00:00:59,250
which I used a lot throughout this course,

23
00:00:59,250 --> 00:01:02,073
but you can use any other folder here of course.

24
00:01:03,230 --> 00:01:06,020
Thereafter, we wanna copy the package .json file,

25
00:01:06,020 --> 00:01:07,850
into this working directory

26
00:01:07,850 --> 00:01:10,090
and then run the npm install command

27
00:01:10,090 --> 00:01:13,583
to install all required dependencies of this project.

28
00:01:15,480 --> 00:01:17,980
There after we can copy the remaining code

29
00:01:17,980 --> 00:01:20,210
in our host machine project folder

30
00:01:20,210 --> 00:01:22,453
to this working directory in the container,

31
00:01:23,650 --> 00:01:28,200
and then also expose the port used by this application.

32
00:01:28,200 --> 00:01:32,120
And in app.js we can see that is port 80,

33
00:01:32,120 --> 00:01:34,993
so therefore I wanna expose port 80 here.

34
00:01:36,110 --> 00:01:37,130
Now last but not least,

35
00:01:37,130 --> 00:01:39,840
we specify the command that should be executed

36
00:01:39,840 --> 00:01:42,830
when this container starts based on this image,

37
00:01:42,830 --> 00:01:46,920
and there for the moment I wanna execute app.js,

38
00:01:46,920 --> 00:01:50,210
with the node runtime.

39
00:01:50,210 --> 00:01:52,230
Which is available because we're using

40
00:01:52,230 --> 00:01:54,013
the node base image.

41
00:01:55,440 --> 00:01:58,960
Now that's my Docker file for this backend here,

42
00:01:58,960 --> 00:02:00,050
nothing too fancy.

43
00:02:00,050 --> 00:02:02,600
It's basically what we did over and over again

44
00:02:02,600 --> 00:02:03,670
throughout this module,

45
00:02:03,670 --> 00:02:06,380
and it is a quite straightforward Docker file

46
00:02:06,380 --> 00:02:08,013
for a node application.

47
00:02:09,289 --> 00:02:14,030
Now, with that edit, we can now build an image.

48
00:02:14,030 --> 00:02:15,500
And for this, first of all,

49
00:02:15,500 --> 00:02:18,330
I'm going to run Docker image prune -a

50
00:02:18,330 --> 00:02:23,330
to remove all unused images I have on my system

51
00:02:23,440 --> 00:02:25,023
to clean up everything there,

52
00:02:26,050 --> 00:02:28,260
and there after with Docker build dot

53
00:02:28,260 --> 00:02:29,610
we can build this image.

54
00:02:29,610 --> 00:02:32,510
I'll give it a tag of goal,

55
00:02:32,510 --> 00:02:35,083
goals node, that's my image name here.

56
00:02:36,260 --> 00:02:39,530
And this will now build this backend image

57
00:02:39,530 --> 00:02:41,240
based on this Docker file,

58
00:02:41,240 --> 00:02:43,180
and since I cleared all images,

59
00:02:43,180 --> 00:02:45,650
it starts by downloading the node image

60
00:02:45,650 --> 00:02:48,030
and then it will go through these instructions,

61
00:02:48,030 --> 00:02:49,880
creating all those layers,

62
00:02:49,880 --> 00:02:52,670
and it will create my own custom image here,

63
00:02:52,670 --> 00:02:55,950
which we then thereafter can use to spin up our container

64
00:02:55,950 --> 00:02:57,470
for this backend.

65
00:02:57,470 --> 00:03:01,333
So let's wait for this image creation to finish.

66
00:03:02,260 --> 00:03:04,210
Here we go. It is finished.

67
00:03:04,210 --> 00:03:05,740
And now with that finished,

68
00:03:05,740 --> 00:03:09,973
we can run a container based on this newly created image.

69
00:03:11,210 --> 00:03:14,030
So I will add a container or I will run a container,

70
00:03:14,030 --> 00:03:17,933
giving it a name of goals, backend, maybe,

71
00:03:18,940 --> 00:03:23,150
and run a deleting it when it gets stopped

72
00:03:23,150 --> 00:03:26,130
and running it in detached mode.

73
00:03:26,130 --> 00:03:29,490
Actually, initially I'll not run it in detached mode,

74
00:03:29,490 --> 00:03:31,720
I'll just run it like this.

75
00:03:31,720 --> 00:03:33,350
And if I now hit Enter,

76
00:03:33,350 --> 00:03:37,750
we will see that this actually starts up.

77
00:03:37,750 --> 00:03:40,060
And initially it looks like everything works,

78
00:03:40,060 --> 00:03:43,760
but after a couple of seconds, it actually crashes here.

79
00:03:43,760 --> 00:03:47,713
And it crashes because it failed to connect to MongoDB.

80
00:03:48,930 --> 00:03:51,440
And that makes a lot of sense here

81
00:03:51,440 --> 00:03:54,420
because we have MongoDB running in a container

82
00:03:54,420 --> 00:03:56,190
exposing its port,

83
00:03:56,190 --> 00:03:59,330
but in the dockerized backend application,

84
00:03:59,330 --> 00:04:02,120
I am reaching out to local host.

85
00:04:02,120 --> 00:04:03,260
And that now,

86
00:04:03,260 --> 00:04:06,520
since this application is now inside of a container,

87
00:04:06,520 --> 00:04:08,080
means that I'm trying to access

88
00:04:08,080 --> 00:04:10,700
some other service on this port

89
00:04:10,700 --> 00:04:13,300
inside of that same backend container,

90
00:04:13,300 --> 00:04:15,400
not on my host machine.

91
00:04:15,400 --> 00:04:18,570
You'll learn about that in the networking module.

92
00:04:18,570 --> 00:04:22,220
And there you'll also learn how you can solve that.

93
00:04:22,220 --> 00:04:26,220
There is a special alternative domain or address,

94
00:04:26,220 --> 00:04:27,430
which you should use here

95
00:04:27,430 --> 00:04:30,763
and that's host.docker.internal.

96
00:04:31,790 --> 00:04:35,420
That's a special address, a special identifier,

97
00:04:35,420 --> 00:04:39,470
which is translated to your real local host machine IP

98
00:04:39,470 --> 00:04:40,573
by Docker.

99
00:04:41,590 --> 00:04:45,600
So if we do that with this MongoDB container,

100
00:04:45,600 --> 00:04:49,230
still up and running, which it is, if we do that,

101
00:04:49,230 --> 00:04:51,600
we should be able to launch this.

102
00:04:51,600 --> 00:04:53,600
So for this, first of all,

103
00:04:53,600 --> 00:04:57,960
I will rebuild this image since I changed the source code,

104
00:04:57,960 --> 00:04:59,193
so let's do that,

105
00:05:00,580 --> 00:05:04,930
and there after, I will run this container again, like that.

106
00:05:04,930 --> 00:05:06,380
And now this looks better,

107
00:05:06,380 --> 00:05:10,280
now we get disconnected to MongoDB log message,

108
00:05:10,280 --> 00:05:12,823
which proves that indeed, this did connect.

109
00:05:14,360 --> 00:05:16,790
So our backend is now dockerized,

110
00:05:16,790 --> 00:05:20,460
it's in a container and it's able to talk to MongoDB,

111
00:05:20,460 --> 00:05:22,740
but at this point, we'll have a new problem.

112
00:05:22,740 --> 00:05:25,290
The React frontend application

113
00:05:25,290 --> 00:05:28,120
will not be able to talk to this backend.

114
00:05:28,120 --> 00:05:31,980
If I go back to my running React application,

115
00:05:31,980 --> 00:05:35,500
if a reload, I get this error, "something went wrong."

116
00:05:35,500 --> 00:05:38,133
And if I opened the developer tools in the browser,

117
00:05:38,970 --> 00:05:42,350
I see that I got this "connection refused" error.

118
00:05:42,350 --> 00:05:46,800
Indeed, the react application fails to talk to the backend

119
00:05:46,800 --> 00:05:50,130
because whilst the backend is running in a container now,

120
00:05:50,130 --> 00:05:54,060
we're not publishing the ports which it exposes.

121
00:05:54,060 --> 00:05:54,893
And therefore,

122
00:05:54,893 --> 00:05:58,060
the frontend trying to talk to this backend application

123
00:05:58,060 --> 00:06:00,283
on specific ports fails.

124
00:06:01,380 --> 00:06:04,270
Now we do have this expose instruction in the Docker file

125
00:06:04,270 --> 00:06:05,990
of the backend application,

126
00:06:05,990 --> 00:06:08,820
but as you learned, this alone doesn't do much.

127
00:06:08,820 --> 00:06:11,470
Instead, you need to publish the ports

128
00:06:11,470 --> 00:06:14,170
that should be available on your local host machine

129
00:06:14,170 --> 00:06:16,460
when you run a container.

130
00:06:16,460 --> 00:06:19,503
So therefore here in a new terminal,

131
00:06:20,410 --> 00:06:23,020
I'll list the running containers,

132
00:06:23,020 --> 00:06:27,010
and I will stop the goals backend container,

133
00:06:27,010 --> 00:06:28,430
which we just started

134
00:06:29,510 --> 00:06:31,180
so that we can restart it

135
00:06:31,180 --> 00:06:34,043
but this time with the correct ports being published.

136
00:06:35,110 --> 00:06:36,860
So now that it's stopped,

137
00:06:36,860 --> 00:06:40,080
we can again run this goals backend container,

138
00:06:40,080 --> 00:06:43,610
but now I will run it in detached mode by adding -d

139
00:06:43,610 --> 00:06:47,070
and very important with the -p option

140
00:06:47,070 --> 00:06:50,040
to publish the internal port 80,

141
00:06:50,040 --> 00:06:52,930
which is exposed by this container

142
00:06:52,930 --> 00:06:55,070
and which is the port on which the application

143
00:06:55,070 --> 00:06:57,180
is listening inside of the container

144
00:06:57,180 --> 00:06:59,203
to my local host, port 80.

145
00:07:00,620 --> 00:07:04,107
And with this, we start this container again,

146
00:07:04,107 --> 00:07:05,750
and it is now up and running.

147
00:07:05,750 --> 00:07:08,290
And now the React application,

148
00:07:08,290 --> 00:07:10,820
which currently is not dockerized yet,

149
00:07:10,820 --> 00:07:13,770
will be able to talk to this backend.

150
00:07:13,770 --> 00:07:16,710
So if I now reload, this error is gone,

151
00:07:16,710 --> 00:07:20,220
and now we should also be able to add a goal,

152
00:07:20,220 --> 00:07:22,143
and if I reload, it's still there.

153
00:07:23,240 --> 00:07:25,670
So now two of three parts

154
00:07:25,670 --> 00:07:28,613
are dockerized only the frontend is missing.

