So let's work on that frontend next,
before we thereafter ensure that data persists,
and source code is updated live.
Let's work on dockerizing this frontend application.
And that's of course something new,
which we haven't done before in this course.
It is, however, not that difficult.
I will stop my running NPM start process
in this frontend folder,
and in order to dockerize this,
here, I also need to write a docker file.
Because I need my own instructions again,
there is no official image for this specific application.
Now, in order to dockerize it,
you need some basic knowledge
about this React project setup.
Otherwise it's hard.
Which is why I mentioned that dockerizing this
would definitely be harder and optional,
and why you should start with backend and MongoDB.
Because you need to know that this frontend setup,
in the end, depends on Node.
It's not a Node application, but it uses Node
to spin up this development server,
which serves this React application,
and Node is also used to optimize the React code
which you write and to transform it into code
the browser understands.
Now, this is just how React projects typically are setup,
and that's why our docker file, in the the frontend folder,
also needs to be based on Node as a base image.
Not because we write Node code ourselves,
but because this project setup requires Node.
As a next step, I will also setup a working directory here,
and we can also name this app,
since it is a totally different container
than the backend, there will be no clash.
So I will go with app here as well,
but you could also use as different name.
Next, we also got dependencies here,
so we should copy package.json into the working directory,
and then run NPM install.
This does not differ from the backend.
It's basically the same.
Now thereafter, I also want to copy the remaining code
into my working directory here.
And once that is done, I want to specify a command
which should be triggered whenever we create a container
based on this image.
And here it's not Node running a file,
but it's NPM start.
Running this start script
in this frontend package.json file.
This then uses one of the installed dependencies
to spin up that development server which hosts this
React application during development.
We'll talk about deployment later in this course.
Now, this application also exposes a port.
We don't see it directly, but by default it's port 3000,
and you could see this before, here,
when I tested this application locally on my host machine.
So therefore, I want to document this, and add expose 3000
to this docker file.
Now, that should be it.
That's a basic docker file for this React application.
If we now save this, we can also docker build this file,
and give it a tag, and I will name it goals react.
Hit enter, and now build this docker file.
So now there's also starts, goes through all these steps,
installs all the dependencies,
which for this project can take a bit longer.
You can ignore any warnings you get here, that's no problem.
And after a while this will eventually finish,
and we'll then have this frontend application
inside a docker image as well.
So let's wait for this image creation
to finish and to be done with.
And you will note that this takes quite some time,
but eventually, it's done.
And now with this done we can run a container.
We can run a container based on
this goals react image we just built,
give the container a name of goals frontend maybe,
remove it when it's stopped,
run it in detached mode if we want to,
and, very important,
publish the internally exposed port 3000
on the local host port 3000
so that we can still enter this here in the browser
and view this application as it's running
on the development server.
So let's hit enter.
With docker PS, we can see that goals react
is a running container now.
And hence if I now reload local host 3000,
I should see this application.
But actually I don't.
And if I run docker PS again,
I indeed see it's not running anymore.
So something seems to go wrong here.
And in order to see what that is, I will rerun it
but now not in detached mode, but instead in attached mode,
so that I can see all the logs.
So let's try this again.
And you see it's starting the development server here,
so that seems to work.
But thereafter it seems to stop.
Because thereafter I can already see
it's not running anymore.
Now why is our container stopping
immediately after this development server was spun up?
Now that's something specific to this React project's
setup here.
You need to run it in interactive mode,
by adding the dash IT option to the docker run command
so that you don't just start the container
and be done with it, but that you let the container know
that you want to be able to also enter commands
and interact with it.
We're not actually going to do that,
but the React project is set up the way
that if it doesn't receive this input,
this input trigger you could say,
it immediately stops the server
because no one's interested anyways.
I guess that's kind of the logic there.
So we need to add dash IT here.
And if I now run this,
now this starts up, starts the development server,
and now this looks much better.
And if we now reload local host 3000,
here's my application.
Now the goal I entered before is missing
because I restarted the MongoDB container in the meanwhile,
but otherwise our goal we added before would still be there.
And if I add a new goal here, you see that works,
and if I reload it's also fetched again.
So, now, this application is dockerized as well,
and the frontend is also running in its own container.
And that's already a great first step.
We put all three building blocks into their own containers.
Now, let's polish this setup though,
and let's add all the extra features we need in reality.
Like for example, persisting data.
But also communication between these containers.
Actually, we can see that they clearly are able
to communicate, but they all communicate with each other
through our local host machine
because we always publish their ports.
This works, but it's even better
if we put them all into one network.
And then they can automatically communicate with each other
just through their container names,
as you learned in the last course section.
So therefore I'll stop all these containers here.
With control C we can get out of this input mode
on the React container.
And then it shuts down automatically as I explained
if it loses this input signal.
And it will also stop the goals backend container here,
and I will also stop the MongoDB container.
So I'll stop all three containers,
so that at the end here, once we're done,
we've got no running container.
And because they all have the dash dash RM flag,
we've also got no stopped containers.
And now, let's again restart them,
but let's insure we put them into one and the same network.