Now, how can we share the finished,
the built images then?
If you inspect your images,
you can see them with Docker images
but where do you find them?
Where are the actual image files?
Well, we're not going to look for files
and send those around.
Instead, Docker has built-in commands for sharing images
because this is a key mechanism of Docker.
Hence it's very convenient to do that.
And when we wanna share images,
there are two main places
where we can push our images to.
That would be Docker Hub
or alternatively, any private registry of your choice.
Docker Hub is simply the official Docker image registry
but there thousands of other services out there,
which also know how to handle incoming images
and which can be used to store and distribute images.
We'll see more of that private registry stuff
in action later once we dive into deployment.
For the moment, however, I'll stick to Docker Hub
because it's also free to use.
At least, you can get started for free.
I recommend the pricing page on hub.docker.com.
There you can find out what's free and what's not
and this Free plan has all the features we need here.
So we can absolutely go with that Free plan for the moment.
And hence, you can already go ahead
and sign up with Docker Hub,
create a free account and choose that free plan
to follow along with me
in the next minutes
because we'll use this official Docker Image Registry
to store our images there.
Now, you can store public or private images there.
And you have these official images like Node and Python,
which you can't add just like this.
They have to be validated and verified officially
but you can bring your own images
and you can control whether everyone is able
to see and use them or whether you wanna restrict usage.
Now, for private registries,
as I said, there are many providers out there.
You can use any provider
that supports Docker images so to say
and there, it then of course,
depends on the provider you're using,
whether everyone is able to see these images
or if it's just you and your team.
That really depends on the provider.
Either way, no matter if you use Docker Hub
or some other provider,
you will be able to share images
by pushing them onto that registry,
so onto Docker Hub
or any other provider and you're then able
to use them, for example, a team member
of yours would be able to use your pushed image
by executing the docker pull command.
Now, important, if you just push and pull
with a regular image repository name,
then this will automatically go to Docker Hub.
If you wanna push or pull to a private registry,
so to any other provider,
you have to include the host,
so the URL of that provider in your push and pull commands.
But again, that is something we'll tackle later
and that's also something which you'll find
in the documentation of whichever provider you're using.
Usage with Docker Hub is extra simple though,
so that's what we're going to do now.
We're going to share our image through Docker Hub.
For that again, make sure you sign up
and you do have an account.
And once you are signed in,
if you wanna share an image,
you can go to repositories
and then click on Create Repository.
Because a shared image is in the end just a repository.
So if you hear the term repository,
I'm talking about an image.
Now, here, you can give this repository any name
of your choice.
Now, let's say we wanna share this node-app
from the last assignment,
which in the end was just a well,
dummy Hello, World-like app
where I just output some message.
Then we could name this node-hello-world.
This name is up to you.
Now, you can also add a description if you want to
and you can choose whether it should be public or private.
Now, in the Free plan,
you have only one private repository available
and therefore, I will turn this
into a public repository here,
which means anyone can download it.
Of course, you should therefore ensure
that your shared application
doesn't expose any security-relevant data
or anything like that.
So public it is.
That's my name.
I need no build settings here
and therefore, I can click Create.
And this now creates a new repository.
Obviously, our repository, which is empty right now,
because we never pushed any image to it.
It shows us the command we can use for that though,
this one here.
Docker push and so on.
So here we can use docker push and copy that,
except for the tag name.
Copy this command.
Go back to our local environment and run it.
And what you'll notice is that this tells you
that you're referring to a repository,
which does not exist locally.
And that's important.
It doesn't exist locally.
And that makes sense.
We created it here in Docker Hub
but how would our local setup know about this?
Well, letting Docker know about it is simple.
It might look strange
but you simply need to give your image this name.
So the name which you might have used anyways
but then prefixed with your Docker ID,
which in my case is academind.
You picked that during signup.
So basically, this here needs to be your image name,
including that slash.
So therefore, if I have a look at all my images here,
I want to turn this node-demo image
into the image that should be pushed to Docker Hub.
And we can do this in two ways.
We can go into the node-app folder
and build this image again
with a tag of academind/node-hello-world.
This would work.
It would create a new image with that correct name.
But if we already got the image,
which we wanna use,
we can also reuse that
because Docker has a command,
which we can use for renaming,
for retagging images.
And that's the docker tag command.
It takes two arguments.
The old name, in this case, node-demo,
and the new name.
To be precise,
we can also specify the full tag here, node-demo:latest.
And then the new name or tag,
which in this case is academind/node-hello-world.
And if we want, we can add a tag here as well
or we omit it and we go just with the name.
If I now hit Enter,
and then docker images again,
we can see that now we've got this new image here.
And it's essentially a clone of the old image,
which also exists and that's important.
When you rename an image,
you don't get rid of the old image.
Instead, you kind of create a clone of the old image,
a clone with that name, which you need.
And with that, if we try pushing again,
now this works
and you see that it starts pushing.
However, you also see
that here I've got an access denied message.
And this makes sense.
This repository is owned by me, by my company, Academind.
I don't want anyone to start pushing there.
Instead, that should only be possible
if you own this account.
And my local Docker command does, of course, not know
if I'm in any way related to this Academind Docker ID here.
So to establish a connection,
we can run docker login.
And you don't need to run this every time you then try
to push thereafter.
Instead, you need to run this once
and you will stay logged in.
There, of course, also is a logout command
in case you ever wanna log out.
But here, we need docker login
and now this asks us for our Docker ID,
which in my case is academind.
And then the password, which I'll quickly enter.
Side note, you don't see the characters
whilst you're typing here.
That's totally normal.
Once I hit Enter,
this logs me in, it succeeded.
And now I can try pushing again.
So now doing this again,
this time it succeeds
and now it pushes this image to Docker Hub
into the repository I created before.
So let's wait for that to finish.
Here it is, it's done.
Side note, it also pushes in a very smart way.
It does not upload my entire image,
which is pretty big.
That would have, here we have a line split
but it has around 950 megabytes.
It's not uploading all of that.
Instead, it, for example, sees that we're relying
on the node image
and that already is on Docker Hub,
so it establishes a connection to that node image
and only pushes the extra code it needs,
only the extra information
and not the entire node image again.
So that's pretty nice.
Saves some space on Docker Hub
and it saves us some bandwidth.
With that, if we go back to Docker Hub
and reload this page,
so this hello-world repository,
we see that we did push now
and we see all the tags we pushed
and latest was the tag that's created automatically
if we didn't set a tag manually.
And of course, if we pushed multiple different tags
with the same repository name,
they would all show up here in this tags list.
So that's something we, of course,
could do to have multiple tags within the same repository.
That is what the Python
and the Node repositories did, for example.