So hard coding the address here
into our front end code is possible
and not really that dramatic.
But we can actually avoid doing that.
By using a trick, which we could have used before too,
but which I now finally wanna show you.
We can use a so-called reverse proxy.
And that's a very fancy term
for one simple thing which we wanna do.
We wanna send the request to ourselves.
And with that I mean to the server,
which serves this frontend application.
So in this case to this nginx server,
which we set up and start in our Dockerfile here
for this frontend.
We wanna send the request to ourself.
Now typically when a request reaches that server,
this frontend application is served.
But we can actually dive
into the configuration of this server,
to generally serve our frontend
but to then also redirect requests to some other host
some other domain if they have a certain structure.
If they target a specific path for example.
And that's this concept which is called reverse proxy.
You can enable it by going to your nginx.conf file
in the conf folder,
and then between listen 80 and location slash,
add location slash API for example.
And this is generally up to you, this slash API part.
This simply means that you now wanna set up
a dedicated configuration for requests
reaching this nginx server where the path,
so the part after the domain or after the IP address,
starts with slash API.
If it starts with anything else,
this configuration will kick in
and will in the end serve your build react application.
So this frontend application.
But if a request should target slash API
or slash API slash something else,
then this configuration will kick in.
And at the moment of course this does nothing.
But that's the part which we can change now.
In here, you can use a special instruction
which nginx understands.
And that's the proxy underscore pass instruction.
This tells nginx that the request to slash API,
so this server slash API should be forwarded
to some other address.
And now here we could grab our URL here
which points at this deployed task service,
and put that here after the proxy path instruction.
Which means requests to this server slash API,
will actually be forwarded
to this address instead.
So they will in the end not be handled by this nginx server,
but by this other server to which they are passed on.
Side note, add a semi colon after this line
to a widen error later which I will face.
Now why is this helpful?
Why could this be interesting?
Well if you save this file now,
you can go to your app.js file
and get rid of the URL in your JavaScript code here.
And instead just send it to the server
you are already running on slash API and then slash tasks.
This here will tell the browser
that it will send the request
to the same server that served this application,
but then they are to slash API slash tasks.
And since we started with slash API here,
it in the end by our server,
will be forwarded to this IP address
which turns out to be the tasks service in this deployment.
And of course I wanna do that
not just for this post request,
but also here in fetchTasks.
Send this to slash API slash tasks.
That leading slash here is important by the way.
So with that we're using this reverse proxy concept.
We are not at the final stage yet.
I wanted to omit this even more
but this is an important first step.
Let's now test whether it works.
And for that,
make sure you go into that frontend folder here,
and then rebuild your image
because you changed the configuration and the source code.
So make sure you run this Docker build dash t
and then your repository image name command again
to update this image.
And thereafter of course also push the updated image
to Docker hub so that Kubernetes
is able to use that latest image.
So once it was built,
of course you also need to push this image here,
like this to Docker hub.
And once this pushing is successful,
we wanna delete the frontend deployment,
and reapply it to fetch that latest code.
And then we wanna see if the application still works.
So let's wait for the push process to finish.
And now that it is finished,
I will go out of this folder
into the Kubernetes folder
and run Kubectl control delete dash f
frontend dash deployment.yaml.
And then again, run Kubectl control apply dash f
frontend dash deployment.yaml,
to reapply it and fetch the latest source code.
So now the containers are again recreated here.
And actually here it crashes and fails to start,
simply because I forgot a semi colon after this here.
And with that semi colon added it will work though.
So I will quickly just rebuild everything therefore
and push it again to apply these changes.
So build DMH again to pick up that latest configuration
with the added semi-colon here.
And once that finished,
I push the updated code to Docker hub of course,
push the updated image I mean,
and once that is pushed
I will delete the deployment which fails to start
and of course redeploy.
So go back into that Kubernetes folder,
run the Kubectl control delete command again
and run the Kubectl control apply command again,
and now it should be deployed successfully.
So now if I get my pods,
this gets created and eventually
it now should start up successfully.
And if you now visit the same IP
from before again and reload,
it'll work again, at least almost.
Where are the tasks?
Well if you open your developer tools, you'll see an error.
That in the end it fails to find this URL.
And the reason for that will be (indistinct) simple.
If I send the request to API slash tasks,
it fails to find that.
And of course it should find that right
because an nginx.config we are redirecting requests
that start with slash API.
Well, yes, but where are we redirecting them to?
We are redirecting them to this IP.
And what could be the problem with that IP now?
This is an IP which we can use on our local machine
to access this cluster which is spun up
and managed by mini cube.
But this configuration indeed
will not be executed on our local machine.
Instead this configuration,
and that's not really the key thing.
This configuration will execute on the server so to say.
It will run inside of the container.
And that's a key difference to our react code
to this JavaScript code in the app.js file for example.
This runs in the browser and therefore technically
outside of the cluster on our local host machine.
The code into configuration however,
is parsed when the server starts
and that happens on the cluster inside of the cluster.
So here, and that's why I'm this reverse proxy.
We can use cluster internal IP addresses.
And we can of course for example also
use our automatically generated domain names.
And that's the cool thing here.
We can use task service dot default for example,
as a domain name.
Because as I explained a couple of lectures ago,
these domain names are generated automatically
for the services registered in your cluster.
And since this code now runs on the cluster,
this can be evaluated and resolved
by Kubernetes and it will actually find our tasks service
when we use this domain.
And that's the cool thing about the reverse proxy
even though our code executes on inside of the browser,
and therefore would normally not run
inside of the container.
With the reverse proxy concept
we can kind of work around that,
and still have code that runs inside of the container
and therefore we can take advantage of things like
the automatic assignment of domain names
and the translation to cluster managed IP addresses.
And I wanna emphasize that this is not some dirty trick,
instead this a quite normal approach
to make something like this work.
And we could have used it before in this course as well
when we deployed to AWS.
It has nothing to do with Kubernetes,
but of course therefore it also works with Kubernetes.
So if we change our configuration like this,
now we should be able to send this request successfully.
Now besides adding this domain name here
there are two other things we gotta do though.
For one, you need a trailing slash here,
and you need a trailing slash here after API.
This might not look like much
but this ensures that the correct path
is later forwarded to your tasks service.
Now one last thing we should do here,
we have to keep in mind that our tasks service
in the end listens on port 8,000.
That's also what we defined in the yaml file
for the tasks service.
It exposes port 8,000
and therefore in this nginx.conf file,
we wanna forward to tasks dash service dot default
colon 8,000 to forward it to this correct port
and not to port 80
which would not be able to handle incoming requests
because it's not the port exposed by the tasks service.
With (indistinct) however, everything will work.
And now we just have to go back into the frontend folder,
and rebuild this image to pick up that latest code
and to push it to Docker hub again.
So run the Docker build command again,
to rebuild this frontend image.
And once it is rebuilt, we'll push it again
so that we can then delete and recreate the deployment
which will pick up that latest image.
So Docker push for the updated image is the next step.
And let's wait for that push process to finish.
And now once that was pushed successfully,
we go back into the Kubernetes folder,
and we Kubectl control delete the old frontends deployment
and then kubectl control apply the same deployment again
but now it will automatically pick up that latest image.
And if you now reload this IP
which serves the react application,
which hasn't changed at all by the way.
This IP address is always the same
because we never removed the frontend service.
You should see your tasks again
and you should be able to add a fourth task
which is maybe learn Docker in-depth.
If you now fetch the tasks again, that also is there.
You can reload and it's still there.
And that all works
now thanks to this reverse proxy concept.
And I wanted to show this to you
because it's a nice way of leveraging,
the automatically generated domain names.
And it ensures that you never have to manually fetch
and enter addresses of your backend services,
into your frontend code here.
You can use this reverse proxy concept instead,
to let Kubernetes give you the IP of that tasks service
and your code does never contain that IP.
Which makes your code more flexible
and allows you to focus on writing your code
and setting up that Kubernetes configuration.
So this is a powerful pattern,
which does not just work with Kubernetes,
but which also works with Kubernetes.
And therefore it's definitely something
which is worth knowing.