For this first of all,
with Docker network LS, we can list DOA level networks.
And here I got this network from the last course section
but I wanna create a new network for this application,
for this demo here.
So, we can do this with docker network create
and then give it any name of our choice
and I'll name it, goals, or goals-net for network.
Hit Enter and this network is created.
With the network created,
we can now start the different containers again,
but now put them all into that network.
And I will start here
by running this mongodb container again.
Now, we no longer need to publish this port
because if containers are in the same network
they can communicate with each other anyways.
My local host machine will not be able
to talk to this container through its local host address
if the port is not published.
But that's no problem
because I don't intend on doing that anyways.
It's enough for me if the free containers
can talk to each other.
So, instead of publishing the port,
I'll add --network and run this container
in the goals net network here.
Like this.
So, now this is starting up and it's up and running here.
So that's the mongodb database
which is now part of this network.
Let's continue with the backend.
Here's our command for running this backend container,
and again, we don't need to publish this port here,
we can just add --network goals-net.
And this will now run this container
in this network as well.
However, before we do that,
let's think about that for a second.
Is this all we need to do?
Well, keep in mind that this backend node application
connects to mongodb and it does that
on host.docker internal.
Now this will fail now because we just started mongodb
without publishing the port,
instead in its own network in the goals net network.
Host docker internal refers to our local host machine though
and there this port will no longer be available
because we're not publishing it anymore,
on the started mongodb container.
Instead here, we should use mongodb,
the name of that container,
which is part of the same network.
So, we need to adjust this code in our backend folder first
and thereafter, we can run this container.
Now that of course means that for the moment at least,
we need to build this image again
and give it this tag of goals-node.
Build this image again, now with the updated source code
where we use the mongodb container name
and once that is done,
only then it makes sense to now run docker run
with that network being used.
So, with --network goals-net.
And now this will start this backend container attached
to the same network as the mongodb container,
and therefore using the name of that mongodb container
will work and docker will be able to connect the two.
So, for now hit Enter, this starts and with docker PS,
we see both containers being up and running.
And of course, make sure you're using the right name here
in your node code.
This really needs to be the name of your mongodb container.
So, now we've got these two containers up and running.
What about react now?
Well, for react, it's quite the same.
There we also need to adjust the code first of all.
In the front end, source folder and there in App JS.
And all the places where I reach out to local host,
this now needs to be the name
of my node application container.
And that was goals-backend.
This name here which I assigned
for starting this goals backend container.
That is what we should use here as an address,
as a domain you could say,
because that can be resolved by docker
to the IP address of our node backend container,
if we run all containers in the same network.
So, that's what we should do here
in App JS and the front end folder
and therefore just as before,
at the moment we still need to rebuild this image.
So, with docker build-t goals react.,
I'm going to rebuild this image.
And again, this takes a short while here,
especially the copy step takes pretty long
because they still have node modules here
and they are also getting here, they are also getting copied
into the container again, and for the front end project,
this is a huge folder,
but we'll take care about optimizing this later.
For the moment it takes a while, but it works.
And thereafter we can run this container again.
Now, however, by also putting it into the same network.
Nonetheless, I still wanna publish my port here
because I still also want to interact with this app
from my local host machine,
so that we can test it in the browser here.
But I will also add --network and add this to goals net.
So that this container is also part of the same network
and is able to communicate with the other containers.
So, let's hit Enter here and let's wait
for this development server to start up,
and then let's reload.
And we get a problem here.
Error name not resolved.
Now, what is the problem here?
Why is this not working?
Well, this is tricky at first,
but it makes a lot of sense if you know how react works
and if you keep in mind and understand
that all the front end react code here,
this JavaScript code, is actually running
in the browser, not on some server.
And that's a key difference compared to this node code.
This is executed by the node runtime on the server,
directly in the container.
For react, that's different, there, we just run NPM start,
which does only one thing, it starts a development server,
which serves this basic react application.
The react code however,
is not executed inside of the container.
This always runs in the browser.
And that means that our nice code here
where we reach out to goals backend,
does not run in the container where docker would be able
to translate this, it runs in the browser
and the browser has no idea what goals backend should be.
And that is not a bug or anything like that.
This is just related to what react is and where it helps us
and that with it you build applications
that run in the browser, not on the server.
And therefore using the container names here,
is simply not an option because this code here
is not executed in a docker container,
it's running in a browser.
The only thing which is running in a docker container here,
is the development server, serving this application,
but that's not enough.
So, what should we do here then?
Well, we should go back to local host
in our react application code, because this is an address
it will be able to communicate to,
our local machine.
This is a address the browser will understand.
And it's all about the browser here,
because again, this code is executed by the browser.
So, local host is an identifier the browser understands.
And with that changed back, we need to ensure
that on local host, these end points can be reached.
And that simply means, that we still need to publish port 80
on the backend application, so that that application
is also still available on local host,
because our front end application needs that access.
Because of the way react works,
and because of the fact that react applications
have browser site JavaScript code, and not JavaScript code
that runs inside of the docker container.
If that would be different,
if we had a second node application
that needs to talk to the first one,
then we could use the container name.
But since this is a JavaScript code running in the browser,
we need code which the browser understands, not docker.
So, long story short, I changed this code
and we can stop this container with Control + C.
We can then rebuild this image,
basically rebuilding the same image we had before,
but I wanted to show you this important case here.
And once this is rebuilt, we can restart this container
and we don't need the --network option here
because this is an option
which doesn't make sense here anyways,
because the part which runs in the container,
the development server, doesn't care about the network,
it doesn't interact with the node API or the database.
And the part that would interact with the API
is not executed in the docker environment.
So, there's no need to add the network here,
instead we run this front end container as we did before.
But now we also need to go back to the terminal
where we started the backend container.
Here, we should stop this goals-backend container.
Make sure you stop this goals backend node container,
and then we should restart it, but we should ensure
that we still publish port 80.
So, we run our docker run command again
for the goals backend.
And we still need the network here,
because the node API still also talks to mongodb.
And we wanna use a network here,
so that we can use the mongodb name here in our node code.
And here it works, because this code executes directly
in the docker container.
So, here docker is able to help us.
But I also still want to publish port 80 on port 80
on the local host machine,
so that our separate react application
is able to talk to that.
So, let's run this.
Let's verify that all containers are up and running
and then let's reload the react app.
And now it works and I can learn docker, reload
and everything is here.
So, we got these free containers up and running
and we got them working with each other.
And especially for react it was a bit tricky,
because the code doesn't run in the container,
but it runs in the browser.
And then docker is not able to help us
with this automatic host IP resolving.
I hope I could explain why that is
and how we can mitigate it.
But we're not done at this point, we got our containers
and we got them talking to each other,
but we got these other things which we wanna add.
Data persistence, limited access
and life source code updates, which are reflected
in the running containers.
So therefore, that is what we'll focus on next.