1
00:00:02,180 --> 00:00:04,490
So let's create our first container.

2
00:00:04,490 --> 00:00:06,180
And let's get our hands dirty,

3
00:00:06,180 --> 00:00:09,040
even though I will say right away that at this point,

4
00:00:09,040 --> 00:00:11,840
we're not going to understand everything here.

5
00:00:11,840 --> 00:00:13,960
We're just going to write some code,

6
00:00:13,960 --> 00:00:15,310
and bring up a container,

7
00:00:15,310 --> 00:00:17,890
and we're going to understand all the details

8
00:00:17,890 --> 00:00:20,660
a little bit later in the next core section.

9
00:00:20,660 --> 00:00:23,740
I just wanna immediately get something up and running,

10
00:00:23,740 --> 00:00:26,550
we also have this example to validate

11
00:00:26,550 --> 00:00:29,190
that everything is working as it should.

12
00:00:29,190 --> 00:00:31,900
So here's the example, you'll find it attached.

13
00:00:31,900 --> 00:00:34,830
It's a very simple Node.js application.

14
00:00:34,830 --> 00:00:36,170
And by the way,

15
00:00:36,170 --> 00:00:38,990
I just wanna highlight, it's just an example.

16
00:00:38,990 --> 00:00:42,330
You don't need to know Node.js for this course.

17
00:00:42,330 --> 00:00:44,700
You can follow along, even if you don't know it,

18
00:00:44,700 --> 00:00:48,180
because we're not going to write any Node.js code.

19
00:00:48,180 --> 00:00:50,900
You can use Docker for any programming language

20
00:00:50,900 --> 00:00:53,843
and any project and application

21
00:00:53,843 --> 00:00:55,870
written with any technologies of your choice.

22
00:00:55,870 --> 00:00:58,250
What you learn in this course will apply.

23
00:00:58,250 --> 00:00:59,540
It's just an example,

24
00:00:59,540 --> 00:01:02,010
because I have to pick some programming language

25
00:01:02,010 --> 00:01:04,000
for the example in the end.

26
00:01:04,000 --> 00:01:08,160
So this is a Node.js application with some basic dummy code.

27
00:01:08,160 --> 00:01:09,000
And in the end,

28
00:01:09,000 --> 00:01:12,210
this will start up a web server on port 3000,

29
00:01:13,366 --> 00:01:17,770
which will listen to get requests on no particular path.

30
00:01:17,770 --> 00:01:21,080
And we'll then send back some dummy HTML.

31
00:01:21,080 --> 00:01:24,180
I also got this dummy database connection code,

32
00:01:24,180 --> 00:01:25,890
which doesn't really connect,

33
00:01:25,890 --> 00:01:28,700
but just set a timer of one second,

34
00:01:28,700 --> 00:01:31,400
until these servers launched in the end.

35
00:01:31,400 --> 00:01:33,190
And I'm having this here so that we have

36
00:01:33,190 --> 00:01:35,680
a top level await example,

37
00:01:35,680 --> 00:01:37,530
which is a Node.js feature

38
00:01:37,530 --> 00:01:40,260
for working with asynchronous code,

39
00:01:40,260 --> 00:01:45,260
which only works if you use Node.js version 14.3 or higher.

40
00:01:45,840 --> 00:01:47,860
So this is the Node.js code.

41
00:01:47,860 --> 00:01:50,140
If we would want to run it locally,

42
00:01:50,140 --> 00:01:52,770
without Docker and without containers,

43
00:01:52,770 --> 00:01:56,850
we would have to visit nodejs.org and then download that

44
00:01:56,850 --> 00:01:58,800
latest version of Node.js,

45
00:01:58,800 --> 00:02:01,540
whichever version that is when you're watching this.

46
00:02:01,540 --> 00:02:03,970
Walk through the installer that gives you,

47
00:02:03,970 --> 00:02:07,060
and then open up a new terminal,

48
00:02:07,060 --> 00:02:10,160
and then run this app mjs file.

49
00:02:10,160 --> 00:02:12,640
By running node app.mjs.

50
00:02:12,640 --> 00:02:14,660
And actually before we do that,

51
00:02:14,660 --> 00:02:16,700
we would have to run another command,

52
00:02:16,700 --> 00:02:20,290
npm install, which installs all dependencies

53
00:02:20,290 --> 00:02:22,510
listed here in packaged.json,

54
00:02:22,510 --> 00:02:24,870
which are simply third-party packages

55
00:02:24,870 --> 00:02:28,200
this app mjs file needs to work correctly.

56
00:02:28,200 --> 00:02:30,600
Again, if that all doesn't tell you too much,

57
00:02:30,600 --> 00:02:32,000
that's no problem here.

58
00:02:32,000 --> 00:02:35,440
These are the steps we just would have to execute,

59
00:02:35,440 --> 00:02:37,880
if we would want to run this code here

60
00:02:37,880 --> 00:02:40,140
locally on our machine.

61
00:02:40,140 --> 00:02:43,150
However, the idea with Docker was a different one.

62
00:02:43,150 --> 00:02:45,450
We want to run this code in a container.

63
00:02:45,450 --> 00:02:47,300
And for that, we first of all,

64
00:02:47,300 --> 00:02:49,420
need to create a so-called image,

65
00:02:49,420 --> 00:02:52,300
because containers are always based on images.

66
00:02:52,300 --> 00:02:54,130
And you're going to learn more about that

67
00:02:54,130 --> 00:02:56,720
and this relation between image and container

68
00:02:56,720 --> 00:02:59,010
in the next course section.

69
00:02:59,010 --> 00:03:01,590
For the moment to create such an image,

70
00:03:01,590 --> 00:03:03,950
we simply create a Docker file,

71
00:03:03,950 --> 00:03:06,900
so a file which is simply named Docker file

72
00:03:06,900 --> 00:03:08,500
without any extension.

73
00:03:08,500 --> 00:03:11,040
And in here, we now describe to Docker,

74
00:03:11,040 --> 00:03:14,380
how our container in the end should be set up.

75
00:03:14,380 --> 00:03:18,150
And we do this by adding a couple of instructions.

76
00:03:18,150 --> 00:03:19,870
Now, since we are going to dive

77
00:03:19,870 --> 00:03:22,540
into images and containers in greater detail

78
00:03:22,540 --> 00:03:24,080
in the next section,

79
00:03:24,080 --> 00:03:25,690
I don't want to waste your time

80
00:03:25,690 --> 00:03:27,030
with a bunch of instructions,

81
00:03:27,030 --> 00:03:29,420
which we don't fully understand yet.

82
00:03:29,420 --> 00:03:32,970
So instead attached to find a finished Docker file,

83
00:03:32,970 --> 00:03:36,150
which in the end just has a couple of instructions

84
00:03:36,150 --> 00:03:39,940
that we want to use Node.js as a base image

85
00:03:39,940 --> 00:03:42,870
so that we want to have Node.js available

86
00:03:42,870 --> 00:03:44,367
inside of our container,

87
00:03:44,367 --> 00:03:46,810
that we have a certain directory

88
00:03:46,810 --> 00:03:48,860
in the container file system.

89
00:03:48,860 --> 00:03:51,010
Every container has its own file system.

90
00:03:51,010 --> 00:03:53,490
So that we want to have a special directory in there

91
00:03:53,490 --> 00:03:55,030
in which you wanna work.

92
00:03:55,030 --> 00:03:57,550
That we then copy the package.json file,

93
00:03:57,550 --> 00:03:59,510
into our working directory.

94
00:03:59,510 --> 00:04:01,540
Then we run the npm install command

95
00:04:01,540 --> 00:04:04,870
to install all the dependencies our application needs.

96
00:04:04,870 --> 00:04:07,530
Then we copy the rest of the code here.

97
00:04:07,530 --> 00:04:11,240
Then we expose port 3000 to the outside world.

98
00:04:11,240 --> 00:04:14,800
Because that's the port our application is listening on

99
00:04:14,800 --> 00:04:16,870
and we wanna be able to reach that port

100
00:04:16,870 --> 00:04:18,579
from outside of the container,

101
00:04:18,579 --> 00:04:20,870
not just from inside the container.

102
00:04:20,870 --> 00:04:25,020
And then we execute app.mjs with the node command,

103
00:04:25,020 --> 00:04:26,180
which is available because

104
00:04:26,180 --> 00:04:28,390
we're running in a node environment.

105
00:04:28,390 --> 00:04:30,600
Again, this was a quick walk through.

106
00:04:30,600 --> 00:04:34,300
The details will follow in the next core section.

107
00:04:34,300 --> 00:04:38,430
Now with the Docker file created, we open up a terminal.

108
00:04:38,430 --> 00:04:39,360
For example, here,

109
00:04:39,360 --> 00:04:43,210
I'm using the terminal integrated into visual studio code,

110
00:04:43,210 --> 00:04:45,300
the editor I'm using here.

111
00:04:45,300 --> 00:04:46,750
And with Docker setup,

112
00:04:46,750 --> 00:04:50,271
which we have at this point, we run Docker build .

113
00:04:50,271 --> 00:04:53,260
and this builds the image the Docker file.

114
00:04:53,260 --> 00:04:56,170
It finds in the directory in which you run this.

115
00:04:56,170 --> 00:04:59,200
And therefore I'm using this integrated terminal here

116
00:04:59,200 --> 00:05:01,390
because this automatically launches

117
00:05:01,390 --> 00:05:03,260
in this project directory.

118
00:05:03,260 --> 00:05:05,270
So any commands I execute here,

119
00:05:05,270 --> 00:05:07,690
run inside of this directory.

120
00:05:07,690 --> 00:05:11,810
So now this will build an image based on this Docker file,

121
00:05:11,810 --> 00:05:14,750
which is the first thing we need to do.

122
00:05:14,750 --> 00:05:16,780
So simply hit enter here.

123
00:05:16,780 --> 00:05:18,520
If you're getting an error at this point,

124
00:05:18,520 --> 00:05:21,570
make sure you got Docker installed and started.

125
00:05:21,570 --> 00:05:24,160
Start Docker desktop if you installed that

126
00:05:24,160 --> 00:05:26,850
and make sure Docker is running in the background.

127
00:05:26,850 --> 00:05:30,070
And therefore at some point, this should then work.

128
00:05:30,070 --> 00:05:34,610
And what this now does is, it grabs this node environment,

129
00:05:34,610 --> 00:05:36,170
which already exists,

130
00:05:36,170 --> 00:05:38,070
it downloads it from the cloud,

131
00:05:38,070 --> 00:05:41,560
from Docker Hub to be precise, but more on that later.

132
00:05:41,560 --> 00:05:43,630
And then it will set up an image

133
00:05:43,630 --> 00:05:45,380
for a container to be launched

134
00:05:45,380 --> 00:05:48,300
with all these setup steps being executed

135
00:05:48,300 --> 00:05:49,720
inside of the image.

136
00:05:49,720 --> 00:05:50,990
So it will give us an image

137
00:05:50,990 --> 00:05:54,490
which has prepared to be started as a container.

138
00:05:54,490 --> 00:05:57,290
So this now walks through all these steps

139
00:05:57,290 --> 00:06:00,170
and after some time it should be done.

140
00:06:00,170 --> 00:06:03,440
You get us successfully built and then some ID

141
00:06:03,440 --> 00:06:05,890
for this image output.

142
00:06:05,890 --> 00:06:07,640
As a side note on Windows,

143
00:06:07,640 --> 00:06:09,890
your output looks slightly different.

144
00:06:09,890 --> 00:06:14,764
There you find the idea of the image which was built here.

145
00:06:14,764 --> 00:06:17,850
Now we can use this ID here,

146
00:06:17,850 --> 00:06:20,190
and then run a container based on this image

147
00:06:20,190 --> 00:06:22,310
with the docker run command.

148
00:06:22,310 --> 00:06:25,600
Like this, docker run, and then the image ID.

149
00:06:25,600 --> 00:06:30,600
However, actually, since our container here has a port

150
00:06:30,899 --> 00:06:33,130
to which you wanna communicate,

151
00:06:33,130 --> 00:06:36,840
we actually need to publish that port on the container,

152
00:06:36,840 --> 00:06:38,040
which we want to run.

153
00:06:38,040 --> 00:06:40,550
And we do it as by adding the -p flag

154
00:06:40,550 --> 00:06:42,340
on docker run here.

155
00:06:42,340 --> 00:06:47,340
And we then publish port 3000 on port 3000.

156
00:06:47,680 --> 00:06:51,780
Which means we can use our local host, on our local system

157
00:06:51,780 --> 00:06:55,280
to reach the application running on port 3000

158
00:06:55,280 --> 00:06:56,850
instead of the container.

159
00:06:56,850 --> 00:06:58,910
Because by default, there is no connection

160
00:06:58,910 --> 00:07:01,970
between container and our host operating system.

161
00:07:01,970 --> 00:07:05,330
If we wanna send HTTP request for example,

162
00:07:05,330 --> 00:07:07,690
to an application running in a container,

163
00:07:07,690 --> 00:07:10,930
we need to open up the port on the container

164
00:07:10,930 --> 00:07:12,560
to which we wanna communicate.

165
00:07:12,560 --> 00:07:16,130
Otherwise it's a locked network in the container and we

166
00:07:16,130 --> 00:07:18,490
can't reach it from outside.

167
00:07:18,490 --> 00:07:20,800
With that however we can hit enter,

168
00:07:20,800 --> 00:07:23,450
and this now we'll run this container

169
00:07:23,450 --> 00:07:25,070
and you can tell that it's running

170
00:07:25,070 --> 00:07:29,090
by the fact that you now can't enter any more commands here,

171
00:07:29,090 --> 00:07:32,320
but that instead, this command is stuck.

172
00:07:32,320 --> 00:07:35,630
It's stuck because we have a running web server.

173
00:07:35,630 --> 00:07:38,250
Now you can visit local host 3000,

174
00:07:38,250 --> 00:07:40,950
and you should see "Hi there!", there.

175
00:07:40,950 --> 00:07:44,170
And that's our first Dockerized application,

176
00:07:44,170 --> 00:07:46,210
even though of course, at this point,

177
00:07:46,210 --> 00:07:48,640
we haven't written the stalker file ourselves

178
00:07:48,640 --> 00:07:51,290
and we don't fully understand what's happening there.

179
00:07:51,290 --> 00:07:53,130
But we're going to learn all of that

180
00:07:53,130 --> 00:07:55,300
throughout the next sections.

181
00:07:55,300 --> 00:07:57,010
To now stop this container,

182
00:07:57,010 --> 00:07:58,670
we can open up a new terminal,

183
00:07:58,670 --> 00:08:00,760
by clicking on this plus here,

184
00:08:00,760 --> 00:08:03,620
and then you can run docker ps,

185
00:08:03,620 --> 00:08:06,350
which will list all running containers

186
00:08:06,350 --> 00:08:08,870
and then grab this name of this container,

187
00:08:08,870 --> 00:08:12,680
which was started, it's an automatic your assigned name

188
00:08:12,680 --> 00:08:15,900
and run dockers stop, and then this name,

189
00:08:15,900 --> 00:08:20,330
and this will now stop this container and shut it down.

190
00:08:20,330 --> 00:08:22,300
This can also take a couple of seconds,

191
00:08:22,300 --> 00:08:25,680
but thereafter this container is not running anymore.

192
00:08:25,680 --> 00:08:27,680
And therefore once this did stop,

193
00:08:27,680 --> 00:08:30,340
if you reload local host 3000,

194
00:08:30,340 --> 00:08:32,342
you can't reach the site anymore.

195
00:08:33,850 --> 00:08:37,280
Although in that terminal, where you ran docker run,

196
00:08:37,280 --> 00:08:40,240
you now are out of this running process again,

197
00:08:40,240 --> 00:08:42,730
and you can enter more commands.

198
00:08:42,730 --> 00:08:46,700
And that's it, that's this very first basic example,

199
00:08:46,700 --> 00:08:47,940
not too fancy.

200
00:08:47,940 --> 00:08:50,900
And of course not a lot of work from our side.

201
00:08:50,900 --> 00:08:54,520
But it shows us that docker was installed successfully,

202
00:08:54,520 --> 00:08:58,870
that it works and that we kind of did create

203
00:08:58,870 --> 00:09:01,230
such a containerized application.

204
00:09:01,230 --> 00:09:05,420
Because we definitely did not install Node.js on our system.

205
00:09:05,420 --> 00:09:08,580
We did not run npm install in this project folder,

206
00:09:08,580 --> 00:09:10,870
to install all third-party dependencies

207
00:09:10,870 --> 00:09:15,200
and still we were able to bring up that web server

208
00:09:15,200 --> 00:09:17,970
and visited on local host 3000.

209
00:09:17,970 --> 00:09:21,023
And that was possible because of Docker.

