Instructor: We're now successfully able
to visit our running web application inside the browser.
But there's one last little thing that I wanna point out.
I'm gonna start my container up using the image
that we've already built, but this time
I'm gonna start up a shell inside the container,
so that we can do a little bit of debugging inside there.
Remember that we can start up a shell
inside of most Alpine-based containers
by running Docker run dash IT,
and I'll put down my container name
of Steven Grider simpleweb
and then I will override the default startup command
with sh.
Remember, this is a reference to the Shell program.
It will start up a shell
that we can type commands into inside the container.
Now you'll notice
that I did not specify a port mapping here.
It's because we are not
going to actually start up the server.
I just want to attempt to look
at the files and folders inside the container.
So I'll run that
and then we'll get a command prompt,
based inside of the root directory of the container.
Now inside of here, I'm gonna print out
all the available files and folders with ls.
So inside of here, you'll notice
that when we did that copy operation,
we copied into the root directory
or the root folder of the container.
And so in this root directory,
we can see the Dockerfile, a package lock dot JSON file,
which is automatically generated by NPM,
package dot JSON, index dot JS,
and all of our install dependencies
were placed into this node modules folder.
And again, these were all placed
into the root directory of this container.
Now, this is definitely not the best practice,
and the reason for that
is that if we happen to have any files or folders
that conflict with the default folder system,
like if we have a folder called var or root or run
or lib, super, super likely for us
to have a folder called lib inside of our project,
we might accidentally overwrite
some existing files or folders inside of the container,
which is definitely not ideal.
So we're gonna make a little change to our Docker file
and rather than copying everything
directly into the root project directory,
we're actually gonna copy everything
into, kind of, a nested directory instead.
Now, rather than just changing
the copy command inside of our Docker file and saying,
oh yeah, copy it into, like, some application folder
or something like that,
there's actually an instruction
that we can use inside the Dockerfile
that is specifically meant to address
this whole issue right here,
of accidentally overriding files or folders
by copying into a root directory.
So let's take a look at what the instruction is.
So we can add the workdir or work directory instruction
into the Dockerfile
and then pass a reference to a folder to it.
Then, any following commands or any following instructions
that we add to our Docker file
will be executed relative to this folder.
So in other words, if we add the workdir and then a folder
above the copy instruction right here,
it will make sure that we only execute,
or excuse me, it'll make sure
that when we actually do the copy instruction
it won't copy it into the root directory,
It'll copy it into the directory that we have specified
as the working directory instead.
So let's try doing that right now.
I'm gonna add in an instruction of workdir,
and then we are going to use
a folder of slash user slash app.
So let's say slash user slash app.
If this folder does not exist inside the container,
it'll be automatically created for us.
Now you might be curious as to why I'm using user slash app.
Well, to be honest, in the Node.js world
it doesn't make a tremendous difference
where you put your application into
in a Linux-based operating system.
There definitely are places that you don't want to put it,
but at the end of the day,
the user folder is a safe place to put your application.
It's specified as the location
for all of user home directories.
Essentially, it's an okay place
for us to put our application.
Now, as I say that,
there's definitely a lot of Linux diehards out there
who would probably disagree with me
and they might say, oh no, you should put this into var
or you should put it into the home directory instead.
So there is some disagreement out there
on where the best place is for your application,
but I can just about guarantee you
that if you put it into user slash app,
you're probably gonna be okay.
Okay, so now we've added in the workdir instruction.
I'm now gonna save the Dockerfile
and then we'll flip back over to our terminal.
I'll exit the running container by typing in exit
and then we're going to make sure
that we first rebuild our container
and then we'll try to relaunch it.
So I'll do a rebuild with Docker build dot.
Oh, let's not forget to tag it.
So Docker build dash T,
your docker ID slash simpleweb, and then a dot.
There we go.
So we're going to rebuild it.
Now, one thing that you'll notice is really interesting
because we made a change to an instruction
above the copy and NPM install,
everything after that instruction has to rerun from scratch,
so we cannot use any cached versions.
In other words, the NPM install command has to run again
and reinstall all of our dependencies,
'cause we cannot use the cached version of that step.
So we got our output here.
Let's try starting up our container again.
I'll first start it up in normal mode
and try to visit it inside my browser.
So we'll do a docker run dash P, to set up a port mapping
and we'll map 8080 to 8080.
And then, the container that I want to run
is Steve Grider slash simpleweb.
So we'll run that and then I'll go back over to my browser.
I'll try to visit localhost 8080
and yep, it looks like we're good to go.
I can refresh the page.
And if we also try to start up a shell inside the container,
we'll see that all of our project directories,
or excuse me, all of our project files
are no longer in the root directory.
To do so, we can either rerun the Docker run command
with the IT and SH attached to it
or we can use that docker exec command.
You'll recall we can use Docker exec
to start up a second process inside of a running container.
Let's try doing it that way,
just for a little bit of variety.
So I will open up a second terminal window.
I'll get the ID of that running container
by using Docker PS.
So here's the ID right here
and then we can attach to that container
and start up a shell inside of it,
by using Docker exec dash IT, the ID of the container
and then the program that we want to run inside of it,
which in this case is shell.
Don't forget the IT, right here,
is to attach standard in and a nice looking terminal
to the shell that starts up.
So I'll run that and you'll notice
that we enter directly in to the user slash app folder
because we had set up that working directory previously.
That workdir instruction, right here,
not only affects commands that are issued later on
inside of our Docker file,
it also affects commands that are executed
inside the container later on
through the Docker exec command.
So if I now do an ls right here,
I'll see all of my project files and folders
nicely isolated inside of the single file.
And I can change back to my root directory
by doing CD forward slash,
print out all the files and folders there with ls
and I'll see
that I do not have any possible conflicts going on.
We have nicely spaced our application,
or kind of, isolated our application
into this folder right here.
All right, so that's pretty much it.
Looking pretty good.
Now, believe it or not,
there is one last little thing that I wanna look at.
So let's do one more quick break
and we'll come back in the next section
and do one quick last little thing.
So I'll see you in just a minute.