-: In last section, we spoke about how we're gonna
solve some issues with the production version
of our container by using a multi-step build process.
By using a multi-step process
we can use different base images.
We can have some amount of configuration
or code that gets executed to build
up our application and then copy
over the result to that, to our actual real phase.
So let's start putting together our docker file
to put this into action.
We're gonna begin by opening up my code editor
and then inside of my root project directory
I'm gonna make a new file called "Docker file".
So inside of here we're gonna have
two distinctly different sections.
We're gonna first write out the section
that's going to install all
of our dependencies and run the NPM run build command.
Now, the configuration that we're going to use
for the first block or kind of this build phase is a lot
of configuration that we've already looked at several times.
So we'll go through it rather quickly.
We'll first say from node Alpine
and then I'm going to tag this face with a name.
I can tag this by saying as
and then providing the name of this phase or this stage.
So I'll call this thing "builder".
Oops, not that I'll call it builder like so.
By putting on "as builder", that means that from this
from command and everything underneath it
is all going to be referred to as the builder phase
and the sole purpose of this phase
is to install dependencies and build our application.
Then after that, we're gonna see all
of the usual configuration that we've been making use of
so far throughout this course.
So I'll specify my work directory of app.
I'll copy over my package.json file to that app directory.
I'll run NPM install.
I'll copy over all of my source code.
So notice now that we are doing this build phase
and we kind of don't have any concern
over changing our source code, we don't have to make use
of that entire volume system anymore.
That volume system that we were put implementing
with Docker Compose was only required
because we wanted to develop our application
and have our changes immediately show
up inside the container.
When we're running our code in a production environment
that's not a concern anymore
because we're not changing our code at all.
So we can just do a straight copy
of all of our source code directly into the container.
After we copy all of our source code over
we'll then execute with the run command NPM run build.
All right and that is it.
That's all we have to do for our builder step.
So again this is going to install dependencies,
run NPM run build and the output of it is going
to be that build folder.
Now, one thing I wanna point out here is
that the build folder will be created
in the work in directory.
So the folder that you and I really care about
like the folder with all
of our production assets that we wanna serve
up to the outside world, the path
to that inside the container will be slash app slash built.
That's gonna have all the stuff we care about.
So that's gonna be the folder that we're going to
eventually want to somehow copy over during our run phase.
Okay, so now that we've got our build phase put together
we're gonna write out the configuration
for the actual run phase.
So this is going to be the phase that says we're
going to use the engine X image where we're gonna copy
over the result of the NPM run build
and then somehow start up Engine X.
So to specify the start of a second phase
all we have to do is say from
and then the name of our base image,
which is Engine X like so.
You'll notice that we did not have to
put any terminology or any syntax in here to specify or say
that the initial phase that we have right here was stopping
by just putting in a second from statement
that essentially says, "Okay previous block all complete
don't worry about it".
Any single block or any single phase here can only
have a single from statement.
So you can kind of imagine that the from statements we put
in here are kind of terminating each successive block.
So then inside of here we're going to write
out the command to copy over that build folder
into this new kinda like Engine X container
thing that we're putting together.
So I'm gonna say copy, and I'm gonna say
that we want to copy something from a different phase.
So I'll put in dash dash from equals builder like so.
So this is saying I want to copy over something
from that other phase that we just were working on.
In this case, we wanna copy something
over from the builder phase.
We'll then specify the folder that we want to copy.
So I'm gonna say app slash build because again
that's the folder that you and I really care about
and then we'll specify where we want to
copy the thing too inside of this kind
of Engine X container that we're putting together.
So the folder that we want to copy this stuff to
and this is kind of a little bit
of configuration around Engine X specifically.
If you go back over here
to the Engine X documentation on Docker hub
and you look at that section that says hosting
some simple content
it's kind of hard to see inside of here
but you'll essentially see, oh
here's the perfect example of it right here.
So if we want to serve up some static HDL content
we just stuff it into this folder
of user share engine X hdml.
So anything inside there is going to be automatically served
up by Engine X when it starts up.
Okay, so we're gonna say user notice how there's
no e in there, it's just USR share engine X html like so
and I'm gonna collapse my sidebar just so
you can see all of that.
Okay and believe it or not, that's pretty much it as far
as actually, you know I'd said over here,
Oh yeah start Engine X.
Well, it turns out that the default command
of the Engine X container or the Engine X image
is gonna start up engine X for us.
So we don't have to actually specifically
run anything to start up Engine X.
When we start up the Engine X container,
it's just gonna take care
of the command for us automatically.
So that's pretty much it that is our docker file
for the developers mean the production environment.
Again, the really important thing to understand here
is that we've got this multi-step process where
we're creating one temporary container right here
or one set of layers right here.
We execute some number of commands inside that set of layers
and then outta that set of layers, we're just copying
over just the bare minimum, just the stuff we care about.
So when we do this copy step right here
we're essentially dumping everything else that was created
while this set of configuration was executed.
So we're not pulling over anything
from the node alpine image,
we're not pulling over any
of the results of the NPM install,
we're not copying over any of our source code.
All we are getting is the result of
that app/build directory.
That's it so our end image is gonna be relatively small.
It's gonna be essentially however large the
engine X base image is and that's pretty much it.
All right, so that's it.
Now let's take a quick pause right here.
I'm gonna make sure I save this file
and then we're going to test this out in the next section.
So quick break and I'll see you in just a minute.