-: In the last section we spoke about
how we're going to put an Nginx server into our application,
its job is going to be watch for incoming requests
and route them off to the appropriate back-end server.
In order to set up Nginx in this fashion
and give it a set of routing rules,
we're gonna create a file called default.com.
This is a very special file
that will be added to an Nginx image
that you and I are going to put together.
This file is gonna add a little bit of configuration
to implement that set of routing rules.
Now, of course this is a course about Docker
not quite about Nginx,
nonetheless, I wanna tell you a little bit
about the configuration we're going to put together
because I really do believe that you're gonna end up
using Nginx on a majority of Docker-based projects.
Maybe not but I wanna at least
give you a little bit of knowledge here.
So, inside of this configuration file
we're going to put down a little bit of configuration
that's gonna set up all the instructions
that you see on the right-hand side.
First off, we're gonna tell Nginx
that there is something called an upstream server
at client:3000 and server:5000.
Let's break down both those statements right there
and kinda quantify what they're trying to communicate.
So, as we just said a moment ago
Nginx is going to watch for requests from the outside world
and then route them to appropriate servers.
These servers are kind of behind Nginx,
you cannot access these servers
unless you go through the Nginx server.
And so Nginx refers to these as upstream servers,
they are servers that Nginx can optionally
redirect traffic over to.
Now, in both these statements
you'll also notice that I said
there is a server at Client:3000 and server:5000.
So, as a quick reminder,
when we put together our initial server implementation,
inside the server directory you'll find that index.js file,
at the very bottom of it you'll see that we are listening
on the server on port 5,000.
So, the server is watching for traffic on port 5,000
and the client as a Create React App application
by default listens for traffic on port 3,000,
so that's where we are getting those two ports from.
Create React App by default port 3000,
our server by default port 5,000.
Now, the client right there, client:3000 and server:5000,
those are both actual addresses.
And so client and server are actual host names
or essentially URLs
that Nginx is going to try to direct traffic to.
We are specifically using client and server right there
because those are the names
of the client and server services
we put together inside of our Docker composed file.
Here's client and up here is server right here.
Remember, anytime you make a Docker composed file
the different service names are essentially used
as domains of sorts,
and you can refer to them in order to access the service
that is hosted by the service.
So that's why we're gonna direct traffic
specifically to client:3000 and server:5000.
After we put together those two quick definitions
we'll then tell Nginx
that it's going to listen by default on port 80.
Now, remember this is port 80 inside the container
and so it doesn't really matter
if we say port 80 or we say port 5 billion,
at the end of the day when we run our Docker composed file
we can change the actual port
that is more or less exposed to the outside world,
or essentially set up that port mapping.
After we do do that
we'll then set up the two roles
that say, "Essentially, if anyone comes to the slash
or kind of route route,
we wanna send them to the client upstream,"
so that's this upstream right here,
"... and if anyone goes to /API,
send them to the server upstream."
All right, so that's what we're gonna do inside this file,
I figured it would be easier to tell you with a diagram
rather than write out the file and tell you along the way.
So, let's now flip over to our code editor
and we're gonna put that file together.
So, to locate this file I'm gonna make a new folder
inside of my route project directory
and I'm gonna call this new folder Nginx.
So, inside of the Nginx folder
I'll make a new file called default.com.
Again, this is a very special file name,
we're going to eventually work it into a Docker file
or, excuse me, a docker image in just a little bit as well,
so make sure you specifically name it default.com.
So, now inside of here we'll set up these two upstreams.
I'll first say upstream client,
this sets up the definition of an upstream called client
and then inside of here we're gonna say that
it refers to a server that is hosted at
client:3000, like so.
And notice how there is a semicolon on the end of the line.
So, again, the syntax here says
there is a upstream, we are calling it client,
it is located at the domain name
or the URL client port 3000.
This right here is how you can access it.
So, now we'll do the same thing for our API as well.
Now, as we put this together
you're gonna notice something a little bit awkward,
it's not gonna say upstream_server_server_server:5000.
Now, when you look at the previous example,
in order to tell Nginx that the location of this upstream
is at client:3000, we use the keyword server right here.
But as we set up our docker composed file
we've been referring to the express API
with the name of server,
that is the name of the service
as we defined it inside of the Docker composed file.
So, as you might imagine,
having upstream_server_server_server,
this is really confusing and in the world of Nginx
server might even be a protected keyword.
And so if we tried using this in our configuration file
we might end up seeing an error because it might say like,
"Hey, why are you putting the word server right here?
I'm Nginx and the word server to me is an operator."
So, just to make Nginx a little bit happy
we're gonna change our terminology for our back-end server,
or the back-end service, of server just a little bit.
So, we're going to refer to this as the API
rather than as the name of server,
and so that also includes our Docker composed file.
Inside of Docker compose,
rather than giving this a name of server
we're going to call it API, like so.
And, again, we're just doing this to make Nginx happy
so that we don't use the word server all over the place,
and probably end up with like a syntax error
when Nginx tries to make use of our default.com file.
Okay, now, again, please make sure you got a semicolon
on the end of that line,
and then underneath those two upstream definitions
we'll then set up this server block
that sets up the main body of configuration.
So, we're gonna say,
"Nginx, we want there to be a server
that listens on port 80."
So, notice how we got server, listen, 80,
and note the semicolon right there.
And then inside of here
we're gonna set up our two routing rules,
we're gonna say, "If anyone ever goes to slash
then setup a proxy and essentially pass through this request
to the client upstream."
So, to do so we say
proxy_underscored_pass_http://frontend, like so.
So, if a request ever comes in
that matches just slash by itself, like so,
take the request and send it off to this upstream.
Excuse me, I put front end in here, I apologize for that
it should be client.
Ugh, I feel so bad about that.
Okay, hopefully you can forgive me for that, I apologize,
it should be client, that's the name of the upstream client.
So, now we're gonna do the same thing for API as well.
I'll say location/API,
"If anyone ever comes here,
then pass this request upstream to http://API, like so."
And then on this rule right here we're actually gonna add in
one other piece of configuration.
Remember how I told you just a moment ago
when a request comes from the browser with a route of /API,
after it goes through Nginx
it trims off that /API part of the request path.
Well, actually that's not a automatic operation
that is actually something that we configure,
so we can figure Nginx to specifically
chop off that first little /API part of the url.
And so to do so, right above the proxy pass part we will say
rewrite /API/parentheses.* /$1 break.
So, this is a rewrite directive or a rewrite rule,
it means apply a reg X of /API,
so essentially match this reg X right here
against the path name,
and if we match anything to this
then take off the /API and leave it as just /$1.
The $1 right here is actually a reference
to whatever text was matched by this Reg X right here,
ao essentially whatever gets matched
will be added or resubstituted in here as $1.
The break keyword on the very end is a directive
and it essentially means,
do not try to apply any other rewrite rules
after applying this one.
So, if we had other rules in place to rewrite the URL
or the path name here, the break keyword essentially means
"Hey, Nginx, don't try to do any other rewrite here."
The reason you put in break right here
is essentially to keep from going through continuous rules
as Nginx rewrites the URL and then tries to match it
to a new route with the new rewritten url.
Then after that we say the proxy pass to /API, like so,
and that's pretty much it.
Now, again, I want you to make sure,
please, please, please double check,
make sure you've got semicolons
on the end of each of the statement lines.
On my screen they're showing up
as that gray that it's kind of hard to see,
just make sure that you got semicolons
on the end of each of those lines.
Okay, so that's pretty much it.
That's all we have to put into our default.com file.
Now, the last thing we have to do,
and I'm going to just throw this at you out of the blue
'cause I didn't really mention it earlier on,
we put together the default.com file
but we need to actually get it into Nginx in some way.
So, if you remember the diagram we were looking at before,
everything else inside of here was a docker container.
Well, that's no different with Nginx,
we're gonna create a separate Nginx container,
we're gonna build a docker file for it
and we're going to essentially get our configuration file
into Nginx through the use of that docker file.
So, let's take a quick pause right here,
we'll come back to the next section.
We're gonna put together a docker file
that is going to create a Nginx custom image
that has a little bit of custom configuration applied to it.
So, quick break and I'll see you in just a minute.