Create a Nginx Reverse Proxy for a Node Server with Docker Compose

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone welcome to W code we're in this video I'm going to show you how to create an engine X reverse proxy for a node server specifically using Express with Docker and Docker compose so before we start just a demonstration of what we're going to build so if we list out all our Docker containers the two of importance here are node C our node container and our engine X container engine X is running on Port 9999 mapped to the same in the container and node is 8888 mapped to the same port in the node container and what we want to do is say we curl directly to our Express server what we get back are the headers so the headers of the request and now if we contact our engine X server what it does is it returns these headers but with the engine X headers appended and this is because we have an Express server of course we'll create all this that just gets the headers from the request and returns them but if it goes through engine X then it adds all these headers through the proxy and forwards it to express and then Express returns these headers but this is just a demonstration of what we're going to be building so yeah enjoy the video so why use engine x with node well engine X can act as a reverse proxy by being placed between clients and node application servers this increases application performance by managing traffic and distributing it among node servers engine X can also cache and serve out static content to clients without contacting the node application servers which decreases the load placed on them so instead of using like um Express static you can use engine X to serve the static content so now let's set up our project to begin let's just create our node node folder first which we'll call server let's add an index.js file let's change directories into this server and then let's initialize it as an es6 project by doing npm init es6 Dy and this will create a package.json and allow us to use import syntax or or ecma script instead of commonjs require and so for this demonstration we'll be using the express library to handle requests so let's install Express from mpm with mpmi Express and now let's just set up a simple Express app which I've got the code right here so what we're just going to do is we're going to import the express Library create an Express app we're going to create um one route that can be accessed with a get request and what we're going to do is we're just going to access the request headers and send back 200 status with these headers and then we're going to listen for incoming requests on local host on server Port which we will provide through um Docker compose with environment variables and now let's create a Docker file to build our image and actually let's clean this up a bit inside our server let's create a source folder so move this in server and then let's place our index.js file inside of there so we can separate out some configuration from the actual source code but now let's create inside our server our Docker file so inside this Docker file we'll use the node 16 Alpine image as the base build so let me get some code to put in here so this node 16 Alpine image uses node version 16 and is based on the Alpine Linux project which is smaller than most based images setting worker here to- server will create a folder called server inside the image where all our code will be placed we then copy over our package.json file and then run mpm install and we do this before copying over the rest of the code to enable some caching we then run mpm start when the build image is launched which is done with CMD and now let's create some mpm start script to actually get the program running and all we're going to do with that is so in here under scripts get rid of Devon test and we'll just do start and we're simply going to do node. source- index.js so all this simple simply does is we when mpm start is ran we will just run whatever is inside this index.js file which essentially starts our express application and now let's start building our engine X reverse proxy to start let's create a folder oh and this should actually be inside server here so move this inside there but let's create a folder now to hold our engine X information let's call this let's just call it engine X and inside here let's place a template configuration file which we will call default. conf. template and this template file here will hold our engine X proxy configuration we use the template extension because we want to work with environment variables inside this file by default the engine X Docker image runs a script that uses EnV subst which is just um a script for environment variable substitution and it does what it does is it replaces environment variables inside here before engine X starts which you will see more of when we actually demonstrate this but let's fill in this configuration file which is simply going to be a server block and here so these are the environment variables and all capitals so engine X Port is the port that engine X is running on engine X host is the domain that engine X is running on server Port right here is the port the node server is running on which will be the same as right here and server host is the address that the node server is running on these are all environment variables that will be replaced by EnV Subs in this template file now more into this let's talk about these directives here so the proxy set header directive is used to add headers to the proxy request so essentially our engine X reverse proxy will receive a request when it receives a request to this location so the root location what it will do is it'll pend all these headers and then pass the request on to our Express server if you want to go more in depth right here so this x forwarded 4 is a request header that identifies the originating IP address of a client connecting to a web server through a proxy this dollar proxy ad X forwarded 4 is a variable handled by engine X that adds the client address host here specifies the host and port number of the server the request the request is being sent to upgrade is used to upgrade an already established connection to a different protocol such as HTTP to websocket it's Supply from the client so if not provided it will not be added to the request so kind of engine X handles this for us anyway and next we have connection which determines whether the network connection stays open after the current transaction ends however the most important part of this is this proxy pass directive and this tells enginex where to forward the request specifically the proxy pass directive is used inside a location context so used inside here to pass a request to a HTTP server here we want engine X to pass on the request to our node server now let's create the docker file that will make our engine X image work with this configuration so inside here let's create another Docker file and let's take um I'm going to take some boiler plate code and place it in here so here we're using engine X 1.8.0 as the base image again with alpine we then create the working directory dc- engine x-t templates and then copy over our template configuration file into it so we copy this configuration into this location in the container after creating this templat directory and the reason we do this is because by default the engine X Docker container reads template files in the dc-in x-t templates and then it looks for anything with the extension. template and then it takes all these results and outputs them to um the the location Das pc-in x-c con. D which is a main configuration file or sorry which is a folder that contains default. com which is ultimately loaded into the main engine X configuration file but we'll probably see you'll see more of this as we start working more but now that we've got our reverse proxy here and our node server here let's work with Docker compose to build our engine X and node images so first let's create a Docker compose yaml file and now the first thing we'll do is let's build our node image first so we're going to create a service so inside here we're using version 3.8 and then we're creating our services and the first is server and here we call the service server and the image node we then provide the location of our Docker file to the build context so we're saying our Docker file is inside- server which it is right here and it's called Docker file which I believe is default but we we just place it in anyway and then we name the container server host which is the environment variable that we will Define and then we map the machine port to the docker container port with the environment variable server Port right here and these environment variables are all provided from ourv file that we will create and now let's set up our engine X service so with Docker compose we can create multiple Docker images and one of these the next one we're doing is going to be our engine X and let me also fix the indentation on this all right so this looks better and so what we do here is we call the service and and image engine X we set restart to always which means that the container will restart automatically if it stops we then provide the location of the docker file to the build contacts which once again is - engine X and our Docker file is right here we set the container name to engine X host envirment variable which we get it all from this EnV file and then we have our ports of mapping our machine port to our Docker container port and so now let's create this EnV file so we'll just call ITV and what we need to do now is just Define our variables so we have our server Port which will be Port 888 engine xort will be 999 9999 and then we have our server host which is the container name which is going to be node C and engine X host is going to be engine XC and remember Docker sets up an internal Network so this is why it doesn't have to be Local Host as these containers will be able to find them find each other over the network through their container name but so essentially now Docker and Docker compose will use this file to populate the environment variables with these values this means that our node server can be contacted at the Domain node C and the port 8888 while our engine X proxy can be contacted at the Domain engine XC and the port 9999 now to run the program let's simply change back to the top level and what we have to do is just run Docker compose up so if we run this just wait for everything to be pulled from dockerhub but we can see our two surfaces here engine X and server and the amount of layers that are being built so we can see node C exited with Code Zero and I believe the reason for this is due to the name let's just call this also just server let's see if that fixes any issues so just Docker compose up essentially what I believe it was doing is it was just taking there we go so what was happening when we called this node is it was us using the bass node image and so there was no uh code being copied in but now that we're using our own custom one we can see Express is listening on Port 8888 and we know that engine X is listening on Port 999 so if we go in here let's do Tucker PS and what we can see right here is we're mapping 888 and our machine to 8888 in Docker and then here is our engine X you can see the names right here so now so let me see if I can zoom in a bit more okay so so let's curl our engine X server and what we get is an empty response and I think I know why but if we curl our Express server which is on 888 we get these headers here which is coming back from here because we're getting the headers and then just sending them back however what we want to do in the purpose of this video is we want to go through engine X and then get this response and so the issue is that inside this file here let's call this reverse proxy as opposed to engine X because if not it's just probably going to pull the it's going to use the engine X image from Docker Hub which will be empty so if we name it reverse proxy let's do Docker comos up now and we can see here actually you can see EnV substitution running on templates and specifically this here so now because of this if we go back in and now let's curl Local Host 999 we can see our headers from engine X have been appended so we're going through engine X and then so we contact engine X it goes through this forwards it to our Express server and it sets these headers and you can see our X forwarded for so if we look here this is our X fored for header host connection all that stuff whereas if we just go through Express we don't have these headers because engine X hasn't put them on and then if we want to look inside say we go Docker exact dasit genx CSH I think is the command yeah sweet so if we look inside here Dash we're inside our Docker container now our engine X1 if we do a cat of this default conf template we can see everything in here and now if we go back and look inside conf D and we cat out default. conf we could see everything substituted in here so we have node C 88888 listen on 9999 all this stuff and essentially we can see our configuration with Ian environment variable substitution has worked but so just exit out of here but so this was my video on using engine X as a reverse proxy for a node server if you have any comments leave me in the questions sorry if you have any questions leave in the comments and I'll try on back to you uh besides that I want to thank you for liking and subscribing today and I hope to see you in the next one have a good one
Info
Channel: WittCode
Views: 2,305
Rating: undefined out of 5
Keywords: WittCode, wittcode, nginx reverse proxy, docker compose, nginx docker compose, nginx environment variables
Id: U60MdJeov_0
Channel Id: undefined
Length: 14min 37sec (877 seconds)
Published: Mon Nov 13 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.