NGINX Crash Course: Web Server, Reverse Proxy & Load Balancer
Key Takeaways
This video covers the basics of NGINX, including its installation, use as a web server, reverse proxy, load balancer, and SSL termination, as well as its configuration for serving static files and caching.
Full Transcript
What is going on guys? Welcome back. In this crash course today, we're going to learn about Engine X, which is one of the most important tools when it comes to professional and scalable deployment of applications. Now, EngineX is essentially a web server, but it can also be used as a reverse proxy. It can be used as a load balancer. It can be used for SSL termination. It has a bunch of different use cases, and all of them are pretty important when it comes to professional deployment of applications. So, this is a must-have tool in your arsenal. And in this video today, we're going to cover the different use cases with examples. So, let us get right into it. All right. So, we're going to learn about engine X in this video today. And I want to get started right away by showing you the definition. So, when you Google engine X, you're going to get on the one hand here this Gemini overview. And also down here, you're going to see the Wikipedia definition. No matter where you go, you're going to see that Engine X is essentially a web server, but also you're going to read everywhere that it can be used as a bunch of different things like a reverse proxy, load balancer, and so on. And my goal for this video today is to show you the various sites, the various use cases of EngineX using simple examples. Now, this is by no means going to be a complete engine X course, especially not in terms of depth. I'm going to show you a bunch of things you can do with EngineX, but I'm going to keep it quite simple and high level. I want to cover a lot of things and then you can go into more details on your own if you want to. But engine X is one of the most important tools in the process of deployment. On this channel, we often times talk about training models, building applications, uh looking at new packages and libraries, doing certain things, but we don't talk too often about the deployment process. And if you don't know how to deploy an application properly, professionally, and in a scalable way, it's basically useless because it cannot actually work in production. it cannot actually be used by a lot of users. So, EngineX is one of the most important tools in your arsenal when it comes to deployment, which is why we're going to learn about it in this video today. Now, let us get started with the installation and the setup right away. This process can be different depending on your operating system. I'm currently on Linux to be precise on Pop OS, which is Ubuntu based. So, in my case, all I have to do is I have to open up the command line and I have to say pseudoapp install Engine X. This is going to install it. In my case, if I type my password now, you're going to see this is already installed. So nothing happens as you can see here. Uh but depending on your operating system, this is going to be different. So just go to engineext.org, go to install and follow the instructions for your respective operating system. Once you have this done, the important thing is to locate the config file. Everything in engine X is based on the configuration and on the config file that contains the configuration. Now this config file can be located in a number of different places. So you want to go to engineext.org. You want to go to the beginner's guide and you want to see down here uh there are three possible locations. One is slash user local engineext conf. Another one is / etsy engineext and another one is / user local etsy engineext. So depending on your installation you're going to have a different um the config file is going to be located at a different uh place and in my case it is located at / etsy engine x. So when I type ls, you can see here I have the engineext.con file. Now by default there is some config in there already which you can use some default config. You can adjust it if you want to. In my case what I did is I just removed everything. I have now an empty events context and an empty HTTP context. So these two empty blocks and we're going to configure everything from scratch. You can do that as well if you want to for learning purposes or you can use an existing config and adjust it. Now, for the sake of completeness, I should mention that there is an approach that we're not going to use in this video today, which is to use the two directories called uh sites available and sites enabled. The basic idea is you put all your different configs for engine X in sites available. So, in here you have the custom config, the default config, the reverse proxy, the mail proxy, whatever configs you want to have. And these are just config files that exist. So these are the same as the engine xcon file that we're going to be uh changing. So we have servers in here. We define locations and all that which we're going to learn about in this video today. But these are just existing. So they're not enabled. They're not actually being used. If we want to use a config like this, we go to sites enabled and we make a link. So sites enabled. Uh basically here now the custom config from sites available is linked here. So this is a link to this config which means it's enabled. But this is also not the case by default. For this you would have to go to the config file. So to the engineext doconfig file and you would have to use an include statement. So uh you would use something like include and then the file that you want to include. Uh I just wanted to mention this for the sake of completeness. If you're interested in that approach where you have all the configs existing and you can enable and disable them by using ln and by using unlink the two uh commands to link and unlink. Um you can do that you can research that. We're not going to do it in this video today. We're going to keep it simple and focus only on this engineext.com file. Now let us briefly talk about the structure of this course today. I want to cover a couple of examples of using engineext in different ways. And we're going to start by using engineext as a basic web server. So just serving static content. Then we're going to use it as a reverse proxy in a simple way just to combine a backend in the front end and run them as a single web application. The idea of a reverse proxy is you have multiple servers in the background and you have one engine X server instance uh between this collection of servers let's say and the client and then the client makes requests to the engine X instance and the engine X instance makes the appropriate requests to the respective servers and then responds to the client. That's the basic uh idea and we're going to use that uh we're going to use engine X to combine a front end and a backend into a single uh server so that we can run everything through port 80 HTTP. Then we're going to look at SSL termination. So we're going to see how we can use certificates uh how we can terminate SSL. So how we can basically encrypt and decrypt the communication uh with a client using engine X. And we're also going to learn how to use engine X as a load balancer afterwards. So we're going to learn how to have multiple servers, so multiple instance of the same backend server, for example, and how we can use engine X to distribute the load to distribute the requests across these servers. Then we're also going to take a look at a simple caching example. And finally, we're going to look at a simple docker compost setup. So this is the plan for this video today. Let's get started right away with a simple web server setup. Now for this I'm going to open up my enginex.com file and I'm going to use a special command here which is just an alias. I called it nv sue because I use nvy usually for neovim. nv sue allows me to use it with pseudo privileges. The basic command I'm using is just pseudoedit. So pseudoedit allows us to edit a file with pseudo privileges while still remaining in our uh in our user essentially. So I'm not actually using the root user. I just use my neural 9 user but I do it with pseudo privileges and this is useful because you can see here that uh I don't have permission to edit these files uh without that command. So if I do nv engineext and I try to change something you're going to see first of all it tells me it's only read uh it's opened in read only mode and if I try to write you can see readonly option uh is set. So I have to do nv sue enginex xconf. This is going to open up a temporary file and then uh this is going to to uh be copied into the actual config file once I'm done. That's the basic idea. Just so you're not confused about the command. Uh in your case you can just use pseudoedit as well or you can go into the root user and use vi or you can use whatever you want. Just wanted to point that out because people otherwise are going to ask me about that command. But the basic idea now is we want to serve static content. Now, we're not really going to focus in this video on the events uh context here. We're going to focus mainly on the HTTP context. And in here, we're going to define uh now for for starters, we're going to define a simple server instance. So, in this context, we want to have a server. And for this server, we want to define a location. Now what we need to define for the server as well is if we don't want to use port 80 we need to define the port that we want to listen to. So there's the directive called listen and here we can provide now a port for example 99999 if we want to uh we can also provide port 80 but this is redundant so you can also just not provide anything. This is going to listen on port 80. But if you want to for some reason be explicit here, you can say listen 80 and this is of course 90 uh listen 80 and it's going to have the same effect as not putting anything there at all. So the interesting thing here now is the location keyword. So we provide after the location keyword a path for example slash for the default route and then in this block here we provide um the root directory for that path. So for example if I want to say that everything that comes after the slash shall be appended to a certain root path. I first of all need to create that directory on my system. So on the server that is running engine X I need to make sure that this exists. And what I'm going to do here is I'm going to go to uh the root directory here. And in this case I created already a data directory. So I did pseudo make directory data. And in this data directory I have nothing right now. So I'm going to say pseudo make directory www. I'm going to enter my password. And in this directory I'm going to create a file which I'm going to call index.html. And here let's just put a simple heading. Hello world. There you go. And let's also say other.html. And let's here say something like other file just so we have two files. And the basic idea now is when someone calls uh or when someone sends a request to the server to the location slash and then for example slash index html/ other html. What I want to do is I want to get the files from this directory. How do I do that? I do that by providing the keyword root and I basically say root data. So slash data www and then just a semicolon. So this is going to basically say that is the root directory and whatever you put here after the slash is going to be put here after the slash. So that is a very basic setup. We can actually go and use this right away. The important thing is we need to load this config. Now first of all we need to start engine X if it's not already running. And one thing that you want to do here is you want to check if something else on your system is using port 80. Maybe you have some docker container running. Maybe you have an Apache server running. Maybe you have some flask application running. I don't know what you're doing on your system, but maybe you have something running. So, you want to type on Linux lsof- i and then port 80. So, colon 80. In my case, nothing is running here. So, I can go ahead and say pseudo engine x. This is going to run engine x. It's going to boot up the instance. And now I can open up a browser. Let me do that here briefly on my other screen. Now, one important thing before I show you the result uh because I ran into this problem right now is when you edit a file with pseudoedit, you need to close it for the changes to be applied. So, you actually want to go to the config file. So, enginex conf and you want to make the change and then you want to close it, then it's going to be applied. And then what you need to do if engine X is already running the first time it doesn't matter but if engine X is already running and you want to apply the changes in the configuration you need to say p sudo engine x and then uh - s reload. This is going to reload the configuration. So it's going to be applied and then when we go to localhost we're going to see the index html file. So you can see here the hello world heading and also if I go here and say slash um slash other.htm html it's going to go to the other file because this is exactly what our config is specifying and what I can do now is I can create multiple such locations so I can go back into the config file with pseudo privileges and I can say I want to have an additional location here location slash uh let's call this /s server one just to see uh what we can do here and essentially I can say that my root directory for this one is I don't know data other stuff just making stuff up right now to show you how it works. Then what I would have to do is I would have to navigate to this uh directory here again. So to slash data I would have to do pseudo make directory other stuff. So I need a password for this. Then I go to other stuff here. I create now again with pseudo a directory server one. And in this server one directory for example I can create now another index html file. I'm not going to use a heading. I'm just going to say you are on server one. There you go. And the idea now is that everything in the URL that has / server one in it will be mapped to data other stuff server one. So whenever I say location server one/ whatever.html, HTML, it's going to be mapped to the file data other stuff server one whatever html. That's the basic idea. And for this to work, I need to of course say pseudo engineext- s reload. And to see what config is currently being used, I can just use dash capital t. This is going to show me that this config is actually active right now. So I can go and say slash server1 and uh actually slashserver1 slashindex.html and you can see this works. Uh I think it should also work with slashind. Yeah, there you go. So this shows me you are on server one. This is how we can map stuff like this. We can also use a different keyword called alias if we want to have a different behavior. For example, if I want to have uh slash whatever, let's say this is my route uh and I want to map this to an alias. So I want to say basically uh let's do slash data server 2. This has a different effect now because this means that whatever is going to be mapped to server 2. So if I go back and I create with pseudo privileges a directory server 2. I can go into it I can create a new index.html file. I can say hello from server 2. Uh I didn't use pseudo now. Great. Hello from server two. And now if I save that and I say again reload, then when I go to slash whatever, uh, did I mess something up? I think so. Oh, of course, because server 2 should not be here, we want to move server two to one directory up. Was this correct now? There you go. This should work now. Forbidden. Oh, this is probably because I'm missing a slash here. So, we need to actually go back into the config and say slash because otherwise this is going to be confusing. Of course, there you go. Hello from server two because basically we're saying that slash whatever slash is an alias for data uh slash data slashs server 2 slash now the current configuration is this one this is now correct so this is the very basic way in which you can serve static files I don't want to talk too much about this there's also some stuff that you can do with reg x here and with certain file types I don't want to focus on that too much because I want to focus on the reverse proxy capabilities on the load balancing and so on so we're going to move on So let us now take a look at a simple example of using engine X as a reverse proxy in order to centralize the routing. So we're going to have multiple servers running on different ports. But we're going to have only a single server for the client to communicate with. So the client can send the requests to the same port to the same server, but EngineX is going to route the requests accordingly behind the scenes. So in this case, we're going to keep it simple. We're going to have a front end and a back end. And the back end is going to be accessible through the API route. So, we're going to use the same server but slash API. In practice, you could also have five different backends, five different APIs that you can access with different routes, but all of them are running, for example, on port 80. This is a common use case for engine X. For this, let me move my browser to the second screen. Let's go to my working directory here. I have prepared a simple backend and a simple front end. The back end is a flask backend. We can take a look at it. It just has a simple hello world endpoint and a simple addition endpoint which takes two integers and returns the result as a string. Uh besides that, we're just specifying a port. If we don't specify one, we're running on 5555. This is going to be interesting later on when we get to load balancing. For now, that's the server. Quite simple. And we also have a uh React front end. This React front end has a simple service TypeScript file where we fetch the hello world message and we also fetch the addition result and then we have a simple component using all of that. We're not going to go into the code too much here just except that we have a front end and we have a back end running on different ports. Uh the front end is running on port 51 uh 73 or 51 what was it? Yeah 5173. Um and the back end is running on port 55 555. So we can actually run them independently here without engine x. What this was uh what this would look like is we would just say npm rundef we would open up a second terminal j current then go to backend and just do a python 3 app. py. So now we have the back end running we have the front end running. Let's go to a different workspace now. Let's go to localhost port 537. Oh, 73. Sorry. There you go. This is now my front end and it would interact with the back end. But since I set it up in a way that it requests on the same port, it's not going to work now. So if I say if I click the buttons, nothing is going to happen just because I already configured it in a way that is going to be uh necessary for our engine X setup. What do I mean by that? If we go into my front end, you're going to see something interesting in I think it was the service TypeScript file. The base URL that we're targeting here is either passed through the environment or it's localhost port 80 because we don't specify a port/ API. Now, we can also comment this out and use this um configuration here. So, we can rerun the same thing. But for this to work now, we would also have to enable coarse and flask. So cross origin resource sharing which means that since this is coming from a different origin, a different port, we need to allow for that. We need to go into our flask code if we want to make this uh work locally. This is now not part of the engine x course. But we would have to say from flask course, which is a package that you need to install import course and then course app to allow for that. Uh now when I run this and I go to the browser this should be possible now. So we get hello world and if I do something like six and four I get 10 as a result. So this works. Um but this is of course not what we want to do. What we want to do is we want to have everything running on the same port. We don't need course in this case. We can just say everything is port 80. Port 80 is communicating with itself. This is the setup that uh is preferred and professional for production. So, we're going to go back into our source code. We're going to go back into the service file, and we're going to change this uh back to the localhost/ API. So, the code is not really important. We're not going to focus on the TypeScript or Python code here today. It's just one example. You need the front end to communicate with the back end and you need to instruct the front end to actually communicate with localhost/appi or whatever you want to call the route not with some port number that um that the server is running on because engineext will handle all of that for us. So we actually want to communicate with engine X. Um and for the back end you can keep the course if you want to but it's not necessary which is also a benefit of using engine X in this case. So let's run this again and let's now configure engine X for this to work properly. So mpm rundef and now let's move this to a different workspace here. Let's move this onto my git section down here. And now what we're going to do is we're going to adjust the configuration again. So we're going to go back to Etsy and engine X. I'm going to zoom in and we're going to say NV sue or pseudoedit in your case probably enginex.com. And now we want to change this configuration so that our two servers are accessible through the same port. So we're going to keep the server. We're going to keep listen 80. We're going to also add a server name. In practice, this would be your domain name. In my case now, this is just localhost. And now we're going to say that the default location so the slash location uh we're going to use a different keyword here which is proxy pass. So this means whatever we get here is going to be passed to a certain endpoint. In our case now this is [Music] http/lohost and we want to access the front end. So 5173 and we're going to provide a slash in the end as well. So that means that whatever we get at this endpoint is going to be redirected to the front end. The same can now be done with a backend. We said we're going to call this API. So the location/ API is going to be passed to the following. We're going to do a proxy pass http slash localhost uh 5555 like this. Uh we don't need that. And that should actually be it. This is the minimal setup. We can also add some stuff like uh proxy set header. So we can also pass information. We can do something like proxy set header uh host and we can say dollar host to also transmit uh the host information and the real IP address and so on. So x real IP should be remote address. This can be useful for logging and for keeping track of everything so that we get this information in the back end and in the front end. But essentially that configuration is enough. So we can now go and actually I should close this. I don't need a second terminal. I can say pseudo engineext-s reload. And now we go back to our browser. This time we don't go to 5173. We go to localhost. Now you can see port 80 localhost is running uh the app and if I click I get a mistake or I get a problem. What is that? Oh okay I get a problem because I'm using https here which is incorrect. So we need to go back to our uh code which is here. So I go back to my frontend code. This seems to be a mistake here in the service ts file. Of course we're aiming for http. I have a third line here. So, HTTP localhost, not HTTPS. This is what we're going to use later when we talk about the SSL termination and the certificates. But, uh, now this should work. I don't even think we need to reload. Let's go back. Okay, seems like I get a bad gateway. So, let's see what the config looks like right now. I'm not sure what the problem is. HTTP http. Okay, the problem is of course not with a config, but the server is not running because I didn't run it. So, we need to do npm rundef otherwise we're not going to be able to access anything. Uh, and now let's go back run this. There you go. We have our front end. And if I now click on fetch hello, I get hello world. And if I add some numbers here, I get the result. And what I can also do now is I can say slash API and I get hello world. And I can say slash API slash add. and I think uh 1020 and I get 30. So I can access the back end and the front end in the same location here or in the same at the same port at least. Um and that is also common use case for engine X just combining everything centralizing everything into one place. All right, next up we're going to take a look at how to use engine X for SSL termination. So how we can use it to allow for encrypted connections, how we can use it to enable HTTPS, not just HTTP. And of course this is done with certificates. So in practice you would go to a trusted authority, you would get a certificate and you would use that. In this case we're going to just use OpenSSL locally to show how it's done. And then you can apply the same process to an actual uh certificate that you get from an authority. But the concept is quite simple. We're also going to redirect all the HTTP requests to the HTTPS endpoint. We're going to see how this is done in engine X. But the idea is the following. We just generate a key pair. We can do that easily. Uh let's go to the current directory. We can do that easily by saying open SSL. Of course, you need to install that if you don't have it. Uh wreck dash x0 uh x509. Uh dash notes dash days. We want to have it for 365 days. valid- new key RSA 248 or 2048. Uh then key out is private key or actually let's call it priv priv key.pm dash out is going to be fullchain.pm and uh the rest is just going to be us pressing enter here. Now we have the certificate or now we have the key pair so to say. We have the private one which is for decryption and we have this for uh encryption and we're going to now provide these two to engine x to actually uh use them for https access. So I'm going to go back here. I'm going to use nv sue again on my config file. And what we're going to do here now is we're going to say we're no longer listening on port 80. we are now listening on 443 with SSL. So this now allows for HTTPS essentially. And um uh what we also need to specify now is the certificate and the certificate key. So SSL certificate is going to be the following home in my case neural 9 documents slashprogramming slashneur 9 / [Music] python/curren and uh then the fullchain.pm PEM and then SSL certificate key is going to be the private key. So the the private keypm and of course we need a semicolon in the end here. That is basically now specifying this is what we use for encryption. This is what we use for decryption. And uh all we need to do now is we need to redirect all the other stuff. So all the stuff that is not HTTPS, all the stuff that is coming in from port 80, we need to redirect it here to port uh 443. And we do that by specifying another server. And this server here is going to listen on port 80. Again, we don't need to explicitly specify it. I'm going to do it anyway. Uh server name is going to be localhost. And then the important statement is we want to say return 301 which is a code for the redirect http slash and then dollar host and then dollar request uri. So we're basically taking the host that was passed and also the path but we are redirecting to our encrypted instance here. So that is essentially the config. It's not very complicated. It's the same as before just that we have now HTTPS. Now keep in mind we still use HTTP internally. So we still don't have to communicate uh internally using HTTPS. We can just keep the communication within the same server. We can keep it unencrypted. Everything is happening between the user and between the engine X instance. However, since our front end is communicating with the EngineX instance, we need to specify that we want to use HTTPS there. So, I'm going to go to my current directory or actually I still have the instance running. So, let's go here and let's change this to be using HTTPS. So now it's communicating here with uh local host but uh 443 communicating with the API here and I think if I didn't forget anything that should be it pseudo engineext-s reload. Now let's go here. Let's go to http isn't redirected properly. Oh, of course I need to specify HTTPS. Otherwise, it doesn't make a lot of sense. So, now it says here, warning potential security risk ahead. I just need to accept that. The reason is because we don't have an actual certificate. Uh, so I'm going to just accept this. And I get a bad gateway probably. Same reason. Front end is not running. npm rundev. There you go. Let's go back. Run this. And now we have our front end. And now I can do hello world. I can increase the numbers here. I can add them. Everything happening via SSH uh SSL sorry. Um so if I try to go to something else, if I try to go to HTTP localhost, you're going to see it redirects to HTTPS. Now another very useful thing that we can do with engine X is load balancing. And the basic idea of load balancing is we have multiple instances of the same application running on different servers. And in order to not overwhelm a single server with all the user requests, what we do is we distribute them using engine X across all these different instances. So if we look at this server running right now, our Flask application, what we could do is we could just run three different instances of that application and then call a different instance depending on uh you know which turn which instances turn it is currently. So what I can do for example is I can open up three more or two more terminals. I can zoom in here. I can zoom in here. And then here I can say python 3app. py and I can say d-port 5555. And then I can navigate here to my current directory as well to the back end. And I can say python 3 app py-port 5556. And then I can do the same thing down here. I can navigate to my current directory to the back end python 3 uh app py d- port 5557. So now I have three instances of the same uh application running and if I go now into my engine xconfig file. So if I say NV sue uh engineext config what I can do is first of all let's get rid of the SSL to not um be confused. So let's get rid of that. Let's get rid of that. Let's also remove this for the sake of simplicity here. Uh let's say listen 80 up here. Let's remove the server down below. So we have our basic setup here again with the front end and the back end. What I want to do now is I want to say up here upstream backend API and in here now I'm going to define three different uh servers. So I'm going to say server localhost 5555 and then I'm going to copy paste that. I'm going to say 5556 5557. I'm going to use semicolons here. And these are now three servers that are considered to be the backend API. And now all I need to do to do load balancing using engine X is I need to replace the slash API localhost 5555 here by just the backend API. So by just saying http backend API that basically means that now we're going to use all these instances uh instead of just one. So I can say pseudo engineext-s reload. Let's go here. The front end is still running. Let's just move it to a different screen. Let's go to this. Let's move it to screen 4 uh or to workspace 4. And now let's um no longer use, of course, https. Let's just go in http. I forgot to change one important thing. We need to also, of course, go back into our back end and change this to HTTP. So this is always important to uh change this accordingly. So now mpm rundef and now I'm going to use chrome here because firefox seems to not be able to realize that I'm no longer using https. Now I have my front end running. If I press fetch hello, I get a request here. I do get a 404. So that is not good. Let's see what the problem is. Uh probably I'm missing a slash again. Is that a problem? Not sure about that. Let's go and try again. Reload. Okay, there you go. Now it works. You can see I get 200 here. I get hello world here. And now if I press the button again, I get it here. If I press it again, I get it here. And if I now spam the button, you can see that the workload is distributed across the three servers. You can see my three instances are running. I'm pressing the button. I'm constantly getting the requests here. Same with this function. If I say add, I constantly get a different I every time get a different uh server handling my request. Of course, I'm just uh I'm just connecting or I'm just communicating with the engine X instance, but behind the scenes, load balancing is happening. And of course, it makes sense if these are actually on different machines. So, this is the idea of load balancing and this is how you do it with EngineX. just provide an upstream um block here or context or uh directive and um then specify the different server IP addresses and then specify backend API. Now next up I want to show you a simple example of caching using engine X. For this I'm going to use a different flask application now. So I'm going to navigate to my working directory and here I have now a cache example which is an app py very very minimalistic we have a s a single route time which returns the time stamp nothing else very very simple but we're going to cache this and the only reason I'm caching this or the only reason I'm using this application to showcase caching is because this is a value that constantly changes so without caching we would get a different value every single time with caching we're going to get a cached response response uh and we're going to only get a new value when the cache is expired. So that is just to showcase the principle. Of course there are many other more reasonable use cases for that. Um but in this case it's just an example to show you how it works and then you can adapt this uh to your respective use case. So we're going to say here uh NV sue and then the config again. And all we want to do now is we want to get rid of that. We want to go to the server and now we're going to specify here in the HTTP context. We're going to say proxy cache path and we're going to say that our cache shall be located in temp and cache. And then we want to say the zone keys_zone is equal to for example my cache. And we want to allocate 10 megabytes for that. So this is how we specify this. And now we're no longer needing this uh API. We're just going to use slash. We're going to use uh proxy pass to port 5000 because this new application is running on port 5000 to not have any conflicts. Then we're going to say proxy cache my cache. So we're using this cache here. and we're going to say proxy_cache valid uh and we're going to say 200 and then 10 seconds. So this means every 10 seconds we're going to actually get a new response and in between we're going to get the cached response. So we can take a look at that. I'm going to say pseudo engineext and then - s um what was it? Reload. And now I'm going to go to my current directory again. I'm going to go to the cache example. I'm going to run the app. py service. And then let's go to localhost. Now it says not found because of course our endpoint is slashtime. And now you can see I get a time stamp. And if I reload, I don't get any new timestamp. But if I wait for 10 seconds, I'm going to get a new time stamp because this is now the cache response. And if I wait for long enough, I'm going to get a new response. Now 10 seconds, I'm al also going to get the cached response. Then after 10 seconds, I'm going to get a new response, a new fresh response, so to say. There you go. And this is how caching basically works. We can go back and look at the config file at C Engine X. And this is the idea. We provide the path, we choose the cache, and we say how long it shall be valid. And last but not least, what I want to briefly show you now is an example using docker compose. So the setup is the following. We have our backend. We have our front end. Uh we have a directory certificate. So inserts you can see we have fullchain.pm. Uh the private key.pm. We have a directory engine x which uh in this directory we have confd in this directory we have a simple configuration file default conf. You can see it's the basic SSL configuration. We have the server port 80 being redirected to the SSL server. We have here again listen 443. We have uh the certificate the certificate key and we have our basic locations. Same as before, nothing new. And uh essentially what we do is we have our docker compos and here we have a bunch of services. We have the front end, we have the back end. This is quite simple. We just build front end. We just build back end. uh we expose the ports that's it and in uh for for the engine X instance we pull the image engine x Alpine we expose these two ports http and https and we load the certificates and the configuration and that's basically it so maybe one more thing that we didn't have before we also have of course the docker file for the back end which is just that not production ready of course we're just using debug mode flask running of the application Uh same for front end. If we look at the docker file, we have npm rundef host being 000000. This is important for the dockerization otherwise it doesn't uh work. But yeah, very minimalistic setup. And then once we have that, we can just say docker compose up and then d-built to build it and then run it. And this essentially accomplishes the same thing. I need to enter a password. But that's um how you can dockerize the process of engineext. Now we have one single port that is targeted all the time. Um okay, we're already using port 80 of course. So I'm going to say pseudo kill all engine X to get rid of that. So let's do this again. And this is essentially going to accomplish the same thing. We're going to have port 443 being used. So let's go here. Uh let's say advanced. Let's say proceed. Unsave. There you go. Fetch. Hello works. Two and two four works. This is the docked version. So that's it for today's video. I hope you enjoyed it and I hope you learned something. If so, let me know by hitting a like button and leaving a comment in the comment section down below. I tried to cover a lot of different aspects of Engine X. I definitely didn't cover everything that you can do with Engine X. I didn't go into a lot of detail. I just wanted to give you an overview so you know what it's about, why it's important because things like load balancing and centralizing everything to a single port and also uh encryption and also caching and other things are super important. So engine X is a really important tool in that uh process of professional deployment which is why you should have heard about it. This video is like a starting point for you to look into more details when it comes to engine X. So I hope you learned something. If you want to support the channel, make sure you subscribe and hit the notification bell to not miss a single future video for free. Other than that, thank much for watching. See you in the next video and bye.
Original Description
Today we learn about NGINX and its various use cases like serving static files, SSL termination, load balancing and more.
◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾
📚 Programming Books & Merch 📚
🐍 The Python Bible Book: https://www.neuralnine.com/books/
💻 The Algorithm Bible Book: https://www.neuralnine.com/books/
👕 Programming Merch: https://www.neuralnine.com/shop
💼 Services 💼
💻 Freelancing & Tutoring: https://www.neuralnine.com/services
🌐 Social Media & Contact 🌐
📱 Website: https://www.neuralnine.com/
📷 Instagram: https://www.instagram.com/neuralnine
🐦 Twitter: https://twitter.com/neuralnine
🤵 LinkedIn: https://www.linkedin.com/company/neuralnine/
📁 GitHub: https://github.com/NeuralNine
🎙 Discord: https://discord.gg/JU4xr8U3dm
Timestamps:
(0:00) Intro
(0:42) Installation & Basics
(5:15) Web Server & Static Files
(16:54) Reverse Proxy
(26:05) HTTPS & SSL Termination
(31:44) Load Balancer
(36:34) HTTP Cache
(39:54) Docker Compose Example
(42:29) Outro
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from NeuralNine · NeuralNine · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Visualizing Stock Data With Candlestick Charts in Python
NeuralNine
Python Beginner Tutorial #1 - Installation and First Program
NeuralNine
Python Beginner Tutorial #2 - Variables and Data Types
NeuralNine
Python Beginner Tutorial #3 - Operators and User Input
NeuralNine
Python Beginner Tutorial #4 - If Statements and Conditions
NeuralNine
Python Beginner Tutorial #5 - Loops
NeuralNine
Python Beginner Tutorial #6 - Sequences and Collections
NeuralNine
Python Beginner Tutorial #7 - Functions
NeuralNine
Python Beginner Tutorial #8 - Exception Handling
NeuralNine
Python Beginner Tutorial #9 - File Operations
NeuralNine
Python Beginner Tutorial #10 - String Functions
NeuralNine
Python Intermediate Tutorial #1 - Classes and Objects
NeuralNine
Python Intermediate Tutorial #2 - Inheritance
NeuralNine
Python Intermediate Tutorial #3 - Multithreading
NeuralNine
Python Intermediate Tutorial #4 - Synchronizing Threads
NeuralNine
Python Intermediate Tutorial #5 - Events and Daemon Threads
NeuralNine
Python Intermediate Tutorial #6 - Queues
NeuralNine
Python Intermediate Tutorial #7 - Sockets and Network Programming
NeuralNine
Python Intermediate Tutorial #8 - Database Programming
NeuralNine
Python Intermediate Tutorial #9 - Recursion
NeuralNine
Python Intermediate Tutorial #10 - XML Processing
NeuralNine
Python Intermediate Tutorial #11 - Logging
NeuralNine
Python Data Science Tutorial #1 - Anaconda and PyCharm Setup
NeuralNine
Python Data Science Tutorial #2 - NumPy Arrays
NeuralNine
Python Data Science Tutorial #3 - Numpy Functions
NeuralNine
Python Data Science Tutorial #4 - Plotting Functions With Matplotlib
NeuralNine
Python Data Science Tutorial #5 - Subplots and Multiple Windows
NeuralNine
Python Data Science Tutorial #6 - Matplotlib Styling
NeuralNine
Python Data Science Tutorial #7 - Bar Charts with Matplotlib
NeuralNine
Python Data Science Tutorial #8 - Pie Charts with Matplotlib
NeuralNine
Python Data Science Tutorial #9 - Plotting Histograms with Matplotlib
NeuralNine
Python Data Science Tutorial #10 - Scatter Plots with Matplotlib
NeuralNine
Python Data Science Tutorial #11 - 3D Plotting with Matplotlib
NeuralNine
Python Data Science Tutorial #12 - Pandas Series
NeuralNine
Python Data Science Tutorial #13 - Pandas Data Frames
NeuralNine
Python Data Science Tutorial #14 - Pandas Statistics
NeuralNine
Python Data Science Tutorial #15 - Pandas Sorting and Functions
NeuralNine
Python Data Science Tutorial #16 - Pandas Merging Data Frames
NeuralNine
Python Data Science Tutorial #17 - Pandas Queries
NeuralNine
Python Machine Learning Tutorial #1 - What is Machine Learning?
NeuralNine
Python Machine Learning Tutorial #2 - Linear Regression
NeuralNine
Python Machine Learning Tutorial #3 - K-Nearest Neighbors Classification
NeuralNine
Python Machine Learning #4 - Support Vector Machines
NeuralNine
Python Machine Learning Tutorial #5 - Decision Trees and Random Forest Classification
NeuralNine
Python Machine Learning Tutorial #6 - K-Means Clustering
NeuralNine
Python Machine Learning Tutorial #7 - Neural Networks
NeuralNine
Python Machine Learning Tutorial #8 - Handwritten Digit Recognition with Tensorflow
NeuralNine
Generating Poetic Texts with Recurrent Neural Networks in Python
NeuralNine
Stock Portfolio Visualization with Matplotlib in Python
NeuralNine
Analyzing Coronavirus with Python (COVID-19)
NeuralNine
Making Text Images Readable Again with Python and OpenCV
NeuralNine
Neural Networks Simply Explained (Theory)
NeuralNine
Motion Filtering with OpenCV in Python
NeuralNine
Top 5 Programming Languages To Learn in 2020
NeuralNine
Simple TCP Chat Room in Python
NeuralNine
Image Classification with Neural Networks in Python
NeuralNine
Edge Detection with OpenCV in Python
NeuralNine
S&P 500 Web Scraping with Python
NeuralNine
Simple Sentiment Text Analysis in Python
NeuralNine
Introduction - Algorithms & Data Structures #1
NeuralNine
More on: Systems Design Basics
View skill →Related Reads
📰
📰
📰
📰
Fixing Alert on Host Resource Pressure in Hermes-Memory-Installer
Dev.to AI
Deploying to AWS Lightsail with a Docker image from ECR
Dev.to · Shayan Araghi
Infrastructure as Code with Terraform: The Basics You Need to Know
Dev.to · Cloud Frontier
We Killed 400 Clients' 5-Second Polling Loop and Cut Server Load by 90%
Dev.to · Krishnam Murarka
🎓
Tutor Explanation
DeepCamp AI