1
00:00:02,160 --> 00:00:04,840
Now, how can we share the finished,

2
00:00:04,840 --> 00:00:06,720
the built images then?

3
00:00:06,720 --> 00:00:08,640
If you inspect your images,

4
00:00:08,640 --> 00:00:11,230
you can see them with Docker images

5
00:00:11,230 --> 00:00:13,320
but where do you find them?

6
00:00:13,320 --> 00:00:16,323
Where are the actual image files?

7
00:00:17,230 --> 00:00:19,670
Well, we're not going to look for files

8
00:00:19,670 --> 00:00:21,410
and send those around.

9
00:00:21,410 --> 00:00:25,460
Instead, Docker has built-in commands for sharing images

10
00:00:25,460 --> 00:00:28,440
because this is a key mechanism of Docker.

11
00:00:28,440 --> 00:00:31,090
Hence it's very convenient to do that.

12
00:00:31,090 --> 00:00:32,830
And when we wanna share images,

13
00:00:32,830 --> 00:00:35,930
there are two main places

14
00:00:35,930 --> 00:00:39,130
where we can push our images to.

15
00:00:39,130 --> 00:00:40,860
That would be Docker Hub

16
00:00:40,860 --> 00:00:45,696
or alternatively, any private registry of your choice.

17
00:00:45,696 --> 00:00:50,630
Docker Hub is simply the official Docker image registry

18
00:00:50,630 --> 00:00:53,800
but there thousands of other services out there,

19
00:00:53,800 --> 00:00:56,750
which also know how to handle incoming images

20
00:00:56,750 --> 00:01:00,720
and which can be used to store and distribute images.

21
00:01:00,720 --> 00:01:03,510
We'll see more of that private registry stuff

22
00:01:03,510 --> 00:01:06,463
in action later once we dive into deployment.

23
00:01:07,310 --> 00:01:10,100
For the moment, however, I'll stick to Docker Hub

24
00:01:10,100 --> 00:01:12,460
because it's also free to use.

25
00:01:12,460 --> 00:01:14,900
At least, you can get started for free.

26
00:01:14,900 --> 00:01:18,740
I recommend the pricing page on hub.docker.com.

27
00:01:18,740 --> 00:01:21,680
There you can find out what's free and what's not

28
00:01:21,680 --> 00:01:25,830
and this Free plan has all the features we need here.

29
00:01:25,830 --> 00:01:29,640
So we can absolutely go with that Free plan for the moment.

30
00:01:29,640 --> 00:01:31,490
And hence, you can already go ahead

31
00:01:31,490 --> 00:01:33,600
and sign up with Docker Hub,

32
00:01:33,600 --> 00:01:37,030
create a free account and choose that free plan

33
00:01:37,030 --> 00:01:38,970
to follow along with me

34
00:01:38,970 --> 00:01:40,230
in the next minutes

35
00:01:41,090 --> 00:01:44,570
because we'll use this official Docker Image Registry

36
00:01:44,570 --> 00:01:47,370
to store our images there.

37
00:01:47,370 --> 00:01:51,210
Now, you can store public or private images there.

38
00:01:51,210 --> 00:01:54,720
And you have these official images like Node and Python,

39
00:01:54,720 --> 00:01:57,010
which you can't add just like this.

40
00:01:57,010 --> 00:01:59,990
They have to be validated and verified officially

41
00:01:59,990 --> 00:02:01,720
but you can bring your own images

42
00:02:01,720 --> 00:02:04,620
and you can control whether everyone is able

43
00:02:04,620 --> 00:02:08,579
to see and use them or whether you wanna restrict usage.

44
00:02:08,579 --> 00:02:10,728
Now, for private registries,

45
00:02:10,728 --> 00:02:13,730
as I said, there are many providers out there.

46
00:02:13,730 --> 00:02:15,270
You can use any provider

47
00:02:15,270 --> 00:02:18,260
that supports Docker images so to say

48
00:02:18,260 --> 00:02:19,660
and there, it then of course,

49
00:02:19,660 --> 00:02:22,270
depends on the provider you're using,

50
00:02:22,270 --> 00:02:24,750
whether everyone is able to see these images

51
00:02:24,750 --> 00:02:26,930
or if it's just you and your team.

52
00:02:26,930 --> 00:02:28,923
That really depends on the provider.

53
00:02:29,830 --> 00:02:32,790
Either way, no matter if you use Docker Hub

54
00:02:32,790 --> 00:02:34,800
or some other provider,

55
00:02:34,800 --> 00:02:37,660
you will be able to share images

56
00:02:37,660 --> 00:02:40,900
by pushing them onto that registry,

57
00:02:40,900 --> 00:02:42,370
so onto Docker Hub

58
00:02:42,370 --> 00:02:45,120
or any other provider and you're then able

59
00:02:45,120 --> 00:02:47,790
to use them, for example, a team member

60
00:02:47,790 --> 00:02:50,890
of yours would be able to use your pushed image

61
00:02:50,890 --> 00:02:55,060
by executing the docker pull command.

62
00:02:55,060 --> 00:02:58,440
Now, important, if you just push and pull

63
00:02:58,440 --> 00:03:01,300
with a regular image repository name,

64
00:03:01,300 --> 00:03:04,010
then this will automatically go to Docker Hub.

65
00:03:04,010 --> 00:03:06,890
If you wanna push or pull to a private registry,

66
00:03:06,890 --> 00:03:08,920
so to any other provider,

67
00:03:08,920 --> 00:03:10,720
you have to include the host,

68
00:03:10,720 --> 00:03:15,070
so the URL of that provider in your push and pull commands.

69
00:03:15,070 --> 00:03:17,640
But again, that is something we'll tackle later

70
00:03:17,640 --> 00:03:19,770
and that's also something which you'll find

71
00:03:19,770 --> 00:03:24,770
in the documentation of whichever provider you're using.

72
00:03:24,950 --> 00:03:27,890
Usage with Docker Hub is extra simple though,

73
00:03:27,890 --> 00:03:29,820
so that's what we're going to do now.

74
00:03:29,820 --> 00:03:33,193
We're going to share our image through Docker Hub.

75
00:03:34,140 --> 00:03:36,100
For that again, make sure you sign up

76
00:03:36,100 --> 00:03:37,680
and you do have an account.

77
00:03:37,680 --> 00:03:39,590
And once you are signed in,

78
00:03:39,590 --> 00:03:41,550
if you wanna share an image,

79
00:03:41,550 --> 00:03:43,730
you can go to repositories

80
00:03:43,730 --> 00:03:46,488
and then click on Create Repository.

81
00:03:46,488 --> 00:03:50,600
Because a shared image is in the end just a repository.

82
00:03:50,600 --> 00:03:52,780
So if you hear the term repository,

83
00:03:52,780 --> 00:03:54,153
I'm talking about an image.

84
00:03:55,530 --> 00:03:58,940
Now, here, you can give this repository any name

85
00:03:58,940 --> 00:04:00,300
of your choice.

86
00:04:00,300 --> 00:04:02,820
Now, let's say we wanna share this node-app

87
00:04:02,820 --> 00:04:04,760
from the last assignment,

88
00:04:04,760 --> 00:04:07,070
which in the end was just a well,

89
00:04:07,070 --> 00:04:09,570
dummy Hello, World-like app

90
00:04:09,570 --> 00:04:12,010
where I just output some message.

91
00:04:12,010 --> 00:04:15,533
Then we could name this node-hello-world.

92
00:04:16,690 --> 00:04:18,519
This name is up to you.

93
00:04:18,519 --> 00:04:21,339
Now, you can also add a description if you want to

94
00:04:21,339 --> 00:04:25,263
and you can choose whether it should be public or private.

95
00:04:25,263 --> 00:04:26,890
Now, in the Free plan,

96
00:04:26,890 --> 00:04:30,030
you have only one private repository available

97
00:04:30,030 --> 00:04:31,400
and therefore, I will turn this

98
00:04:31,400 --> 00:04:33,690
into a public repository here,

99
00:04:33,690 --> 00:04:36,930
which means anyone can download it.

100
00:04:36,930 --> 00:04:38,670
Of course, you should therefore ensure

101
00:04:38,670 --> 00:04:40,630
that your shared application

102
00:04:40,630 --> 00:04:44,160
doesn't expose any security-relevant data

103
00:04:44,160 --> 00:04:45,433
or anything like that.

104
00:04:46,370 --> 00:04:48,230
So public it is.

105
00:04:48,230 --> 00:04:49,380
That's my name.

106
00:04:49,380 --> 00:04:51,740
I need no build settings here

107
00:04:51,740 --> 00:04:54,188
and therefore, I can click Create.

108
00:04:54,188 --> 00:04:57,503
And this now creates a new repository.

109
00:04:58,410 --> 00:05:01,600
Obviously, our repository, which is empty right now,

110
00:05:01,600 --> 00:05:05,010
because we never pushed any image to it.

111
00:05:05,010 --> 00:05:07,850
It shows us the command we can use for that though,

112
00:05:07,850 --> 00:05:09,080
this one here.

113
00:05:09,080 --> 00:05:12,090
Docker push and so on.

114
00:05:12,090 --> 00:05:15,500
So here we can use docker push and copy that,

115
00:05:15,500 --> 00:05:16,943
except for the tag name.

116
00:05:17,830 --> 00:05:19,780
Copy this command.

117
00:05:19,780 --> 00:05:23,773
Go back to our local environment and run it.

118
00:05:24,810 --> 00:05:27,600
And what you'll notice is that this tells you

119
00:05:27,600 --> 00:05:30,130
that you're referring to a repository,

120
00:05:30,130 --> 00:05:32,990
which does not exist locally.

121
00:05:32,990 --> 00:05:34,010
And that's important.

122
00:05:34,010 --> 00:05:36,230
It doesn't exist locally.

123
00:05:36,230 --> 00:05:37,500
And that makes sense.

124
00:05:37,500 --> 00:05:40,100
We created it here in Docker Hub

125
00:05:40,100 --> 00:05:44,030
but how would our local setup know about this?

126
00:05:44,030 --> 00:05:47,300
Well, letting Docker know about it is simple.

127
00:05:47,300 --> 00:05:48,870
It might look strange

128
00:05:48,870 --> 00:05:52,660
but you simply need to give your image this name.

129
00:05:52,660 --> 00:05:55,760
So the name which you might have used anyways

130
00:05:55,760 --> 00:05:59,860
but then prefixed with your Docker ID,

131
00:05:59,860 --> 00:06:02,160
which in my case is academind.

132
00:06:02,160 --> 00:06:04,350
You picked that during signup.

133
00:06:04,350 --> 00:06:07,800
So basically, this here needs to be your image name,

134
00:06:07,800 --> 00:06:09,533
including that slash.

135
00:06:09,533 --> 00:06:14,130
So therefore, if I have a look at all my images here,

136
00:06:14,130 --> 00:06:17,290
I want to turn this node-demo image

137
00:06:17,290 --> 00:06:20,630
into the image that should be pushed to Docker Hub.

138
00:06:20,630 --> 00:06:23,260
And we can do this in two ways.

139
00:06:23,260 --> 00:06:25,870
We can go into the node-app folder

140
00:06:25,870 --> 00:06:27,870
and build this image again

141
00:06:27,870 --> 00:06:32,143
with a tag of academind/node-hello-world.

142
00:06:33,560 --> 00:06:34,690
This would work.

143
00:06:34,690 --> 00:06:38,443
It would create a new image with that correct name.

144
00:06:39,350 --> 00:06:41,150
But if we already got the image,

145
00:06:41,150 --> 00:06:42,350
which we wanna use,

146
00:06:42,350 --> 00:06:44,390
we can also reuse that

147
00:06:44,390 --> 00:06:46,340
because Docker has a command,

148
00:06:46,340 --> 00:06:49,010
which we can use for renaming,

149
00:06:49,010 --> 00:06:51,610
for retagging images.

150
00:06:51,610 --> 00:06:54,300
And that's the docker tag command.

151
00:06:54,300 --> 00:06:56,180
It takes two arguments.

152
00:06:56,180 --> 00:06:58,880
The old name, in this case, node-demo,

153
00:06:58,880 --> 00:07:00,550
and the new name.

154
00:07:00,550 --> 00:07:01,710
To be precise,

155
00:07:01,710 --> 00:07:06,710
we can also specify the full tag here, node-demo:latest.

156
00:07:07,110 --> 00:07:09,290
And then the new name or tag,

157
00:07:09,290 --> 00:07:12,953
which in this case is academind/node-hello-world.

158
00:07:14,130 --> 00:07:17,040
And if we want, we can add a tag here as well

159
00:07:17,040 --> 00:07:20,113
or we omit it and we go just with the name.

160
00:07:21,360 --> 00:07:22,990
If I now hit Enter,

161
00:07:22,990 --> 00:07:25,240
and then docker images again,

162
00:07:25,240 --> 00:07:29,213
we can see that now we've got this new image here.

163
00:07:30,080 --> 00:07:32,350
And it's essentially a clone of the old image,

164
00:07:32,350 --> 00:07:34,820
which also exists and that's important.

165
00:07:34,820 --> 00:07:36,850
When you rename an image,

166
00:07:36,850 --> 00:07:38,800
you don't get rid of the old image.

167
00:07:38,800 --> 00:07:42,360
Instead, you kind of create a clone of the old image,

168
00:07:42,360 --> 00:07:44,563
a clone with that name, which you need.

169
00:07:46,380 --> 00:07:51,340
And with that, if we try pushing again,

170
00:07:51,340 --> 00:07:53,140
now this works

171
00:07:53,140 --> 00:07:56,180
and you see that it starts pushing.

172
00:07:56,180 --> 00:07:57,320
However, you also see

173
00:07:57,320 --> 00:08:00,692
that here I've got an access denied message.

174
00:08:00,692 --> 00:08:02,730
And this makes sense.

175
00:08:02,730 --> 00:08:06,990
This repository is owned by me, by my company, Academind.

176
00:08:06,990 --> 00:08:10,600
I don't want anyone to start pushing there.

177
00:08:10,600 --> 00:08:13,000
Instead, that should only be possible

178
00:08:13,000 --> 00:08:15,650
if you own this account.

179
00:08:15,650 --> 00:08:19,460
And my local Docker command does, of course, not know

180
00:08:19,460 --> 00:08:24,460
if I'm in any way related to this Academind Docker ID here.

181
00:08:25,070 --> 00:08:27,150
So to establish a connection,

182
00:08:27,150 --> 00:08:29,630
we can run docker login.

183
00:08:29,630 --> 00:08:32,950
And you don't need to run this every time you then try

184
00:08:32,950 --> 00:08:34,270
to push thereafter.

185
00:08:34,270 --> 00:08:36,010
Instead, you need to run this once

186
00:08:36,010 --> 00:08:38,140
and you will stay logged in.

187
00:08:38,140 --> 00:08:40,960
There, of course, also is a logout command

188
00:08:40,960 --> 00:08:43,023
in case you ever wanna log out.

189
00:08:44,070 --> 00:08:46,339
But here, we need docker login

190
00:08:46,339 --> 00:08:50,210
and now this asks us for our Docker ID,

191
00:08:50,210 --> 00:08:52,470
which in my case is academind.

192
00:08:52,470 --> 00:08:55,123
And then the password, which I'll quickly enter.

193
00:08:56,280 --> 00:08:58,300
Side note, you don't see the characters

194
00:08:58,300 --> 00:08:59,640
whilst you're typing here.

195
00:08:59,640 --> 00:09:00,993
That's totally normal.

196
00:09:02,220 --> 00:09:03,280
Once I hit Enter,

197
00:09:03,280 --> 00:09:06,050
this logs me in, it succeeded.

198
00:09:06,050 --> 00:09:08,540
And now I can try pushing again.

199
00:09:08,540 --> 00:09:10,380
So now doing this again,

200
00:09:10,380 --> 00:09:11,910
this time it succeeds

201
00:09:11,910 --> 00:09:16,000
and now it pushes this image to Docker Hub

202
00:09:16,000 --> 00:09:19,090
into the repository I created before.

203
00:09:19,090 --> 00:09:21,460
So let's wait for that to finish.

204
00:09:21,460 --> 00:09:23,260
Here it is, it's done.

205
00:09:23,260 --> 00:09:26,330
Side note, it also pushes in a very smart way.

206
00:09:26,330 --> 00:09:29,170
It does not upload my entire image,

207
00:09:29,170 --> 00:09:31,120
which is pretty big.

208
00:09:31,120 --> 00:09:34,870
That would have, here we have a line split

209
00:09:34,870 --> 00:09:38,330
but it has around 950 megabytes.

210
00:09:38,330 --> 00:09:40,270
It's not uploading all of that.

211
00:09:40,270 --> 00:09:43,240
Instead, it, for example, sees that we're relying

212
00:09:43,240 --> 00:09:44,760
on the node image

213
00:09:44,760 --> 00:09:47,080
and that already is on Docker Hub,

214
00:09:47,080 --> 00:09:50,100
so it establishes a connection to that node image

215
00:09:50,100 --> 00:09:52,810
and only pushes the extra code it needs,

216
00:09:52,810 --> 00:09:55,070
only the extra information

217
00:09:55,070 --> 00:09:57,380
and not the entire node image again.

218
00:09:57,380 --> 00:09:58,740
So that's pretty nice.

219
00:09:58,740 --> 00:10:01,240
Saves some space on Docker Hub

220
00:10:01,240 --> 00:10:03,363
and it saves us some bandwidth.

221
00:10:04,630 --> 00:10:06,610
With that, if we go back to Docker Hub

222
00:10:06,610 --> 00:10:08,123
and reload this page,

223
00:10:09,670 --> 00:10:11,870
so this hello-world repository,

224
00:10:11,870 --> 00:10:13,890
we see that we did push now

225
00:10:13,890 --> 00:10:16,650
and we see all the tags we pushed

226
00:10:16,650 --> 00:10:20,530
and latest was the tag that's created automatically

227
00:10:20,530 --> 00:10:23,090
if we didn't set a tag manually.

228
00:10:23,090 --> 00:10:26,610
And of course, if we pushed multiple different tags

229
00:10:26,610 --> 00:10:28,610
with the same repository name,

230
00:10:28,610 --> 00:10:32,450
they would all show up here in this tags list.

231
00:10:32,450 --> 00:10:33,830
So that's something we, of course,

232
00:10:33,830 --> 00:10:37,930
could do to have multiple tags within the same repository.

233
00:10:37,930 --> 00:10:39,270
That is what the Python

234
00:10:39,270 --> 00:10:42,223
and the Node repositories did, for example.

