At the moment, this basic utility container,
which I created here, allows us to run any command.
Now that is useful, that is definitely not too bad.
But maybe we know that it should be a utility container,
a utility image, which allows us to run npm commands.
So not any command, but restricted to npm.
For example, npm init for initialization.
But then npm install for installing.
Of course, we can do this.
I can run npm install here,
but maybe I just want to run docker run, it,
then my bind mount, then the image name,
and then just install.
And under the hood, inside of the container
that should prepend npm here to run npm install.
So that we have a more restricted utility container
where we can't do everything.
Also to protect ourselves,
so that I don't accidentally run some command
in the container, which deletes everything.
And then because of the bind mount,
it starts deleting content on my host machine as well.
So for this reason, as well, it might be interesting
to restrict the commands we can run.
And for that, we got an extra instruction in the Dockerfile,
which we haven't used thus far.
And that's the entrypoint instruction.
It is quite similar to the command instruction,
but it has one key difference.
If we add a command after the image name on docker run,
then this command, in this case npm install
overwrites the command specified in a Dockerfile.
If there is one.
We didn't have one thus far.
But if we had one, this command in the Dockerfile
would be overwritten by this command
after the image name on docker run.
With the entrypoint that's different.
For the entrypoint, whatever you enter here
after your image name on docker run
is appended after the entry point.
And that's pretty cool.
That means that here, we could specify npm.
And now we could append any npm command after our image name
once we rebuild this image.
So let's do that.
Let's add this entrypoint.
And then let's build this image again,
maybe with a tag of mynpm,
because it's my own version of npm in a container.
So let's do that.
And then we can run docker run mynpm in interactive mode,
in case some input is required from our side
with our volume added.
So again, I'll copy this path,
I will delete this package.json file by the way,
so that we can recreate it and see that in action.
Then use my absolute path here for the bind mount.
And bind this to slash app,
which is the folder inside of the container
against which these commands will be executed.
Entrypoint also adheres to work directory.
And then here after my npm, so after this image name,
I just need to run init, not npm init,
but just init.
Because we have npm already in the entrypoint.
And if I hit Enter,
now again, we can go through these questions
and once we're done, we got this package.json file.
And now we can run any npm commands against this.
For example, npm install.
If I add install here, this now installs
all the dependencies it finds in package.json.
And keep in mind by the way,
that the container always shuts down
once the command is done.
But it was still able to run npm install here,
because of course, since my local folder is the bind mount,
the package.json file, which I already had
was copied into the app folder,
and therefore npm install being executed in the app folder,
was able to pick up this package.json file
and use it inside of the container.
Now I deleted the package lock.json file,
because of course here the install command
didn't do too much.
Since we got absolutely no dependencies specified
in package.json.
Well, we could add them manually here
by adding a dependencies node and adding dependencies
in case we know their names and versions.
Or again, we don't do this,
and instead I run my npm image with install
and then here I could add express
and this would install the express dependency,
maybe with the dash dash save flag,
which is a flag the npm install command accepts
to add express as a package as a dependency to this project.
So for now hit Enter this now installs express,
and you see it creates the node_modules file
and mirrors that back into our local folder here
because of that bind mount.
So that's really useful
and that's a pattern you will also see
in many Docker project,
and it's also a pattern we will use
in some parts of this course.
Now nonetheless,
at the moment our approach here has a downside.
It has a disadvantage.
We have to run these relatively long commands
in the terminal in the command prompt.
And we already learned about a solution for that.
We learned about Docker-compose.
So maybe it can help us here as well.