Deploy React and NodeJS on Linux

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's going on everybody i'm well button this is devops for developers and in this video i'm going to show you how to build and deploy a node.js application on a linux server from complete scratch starting at ground zero so along the way we'll obviously install node.js we'll deploy our code to it and then we're gonna run node.js as a service using a user account that doesn't have any permissions so that we can avoid like privilege escalation security issues we're going to put it behind an nginx reverse proxy so i'll show you how to do that and we'll also use ssl so that all the traffic coming into our server is protected and then after we go through all of that i'm going to show you why i rarely ever actually do it this way for my clients or for my own applications and that's not just some kind of like click-baity stuff to get you to try and watch the whole video the reasons that i have for doing this or not doing it this way will be much more clear once we go through this process of doing it the hard way then you'll be primed to have the conversation about why i have a different way of doing it and i'll tell you what that is so let's just jump right in and see where we're starting at [Music] [Applause] [Music] [Applause] [Music] [Applause] so let me start by showing you the end application that we're gonna deploy i don't think it makes a huge difference other than you'll at least have an idea of what we're building here and this is it it's a react node.js starter app that i got from the internet just to have something to deploy now this actually consists of two different node applications we've got the react application that provides our dashboard our ui our front end here and then there's a second node.js application that provides the back end api that this ui gets its data from and that's actually a pretty common strategy or common scenario that you will encounter a lot following and falling into like the microservices architecture so i thought it'd be a good example to show you here so let's start by sshing into the server that i've built and uh that's the key i'm looking for right there so if we take a look at this ssh command i've got the ssh here which obviously is the command right and then at the end down here i'm going to log into my server as a user named ubuntu we've got the at sign and then the ip address of my server all right now this part in here you may not be familiar with i actually log into a lot of different servers throughout the course of my day and i use different ssh keys for different purposes right and so if you only have one ssh key then without this flag ssh will use your default ssh key the dash i here is just me saying don't use the default key instead use the key in my dot ssh folder named will button aws all right now that's out of the way we'll log in here and we are magically in our server as the user ubuntu now we've got a couple of different directions we can go right away here if i'm the only one that's going to be using this server the only one logging in i think it's probably okay to install node.js and run it as my user important distinction here is that i want to run it as my user not as the user root likewise whenever i ssh in here if i were to log in as root on this system i want to create a user account because we don't want to use the root credentials really at any point until we actually have to and then we only want to do so using the context of the sudo command all right that's out of the way let's just create a user account just so i can show you what that looks like um jump back into chrome here to add user because i don't remember what the command is we'll just try this link here oh sudo ad user well that was challenging wasn't it so let's do sudo add user we'll call it node password password seems to be fine room number i don't know what the room number is yeah that's fine okay so now we've got our user named node so we can change to that user using the sudo su command and now if we type who am i i'm node now the reason i do that is if i have multiple people logging into this server if i've got an account and you've got an account and everybody else on our team has an account we don't really know who's running the node application right so we'll create a node user and that node user will be the one that is running our node process if i do a pwd print print working directory i'm in the home account for node and so now let's go get the code for our application do we have get installed we do all right so if we do git clone and then paste in the url to our dashboard app there's that and then we'll do the same thing for our api server and there's that so if we do ls we've got our api server and our dashboard code on the server in the home directory of our node user but we don't have node and i like to use nvm to install and manage my node installation so let's go over here to the nvm website and we can install that using this command here so we'll do that that's going to run now it's still not installed right because i need to log out and now we'll do sudo su node again all right so we're logged back in as node as the node user and let's type in the command node which isn't going to work because we haven't actually installed node yet but we have installed nvm which is now working so let's do nvm install 16. is that going to work for us yep and that's going to download the latest build for node version 16 and this is why i like using nvm because it's super easy to install different versions of node so whenever node version 16.15 comes out we can easily update to it or whenever 18 comes out we can jump to 18 and if we find out that doesn't work for us it's easy to roll back to the version that was working prior to that so now if we do node v we're running nodejs version 16.14.0 and we've got our code installed so we need to do a little setup here so let's start with our api server going into there and we'll do yarn command which isn't installed so then let's do npm install that should work and that's going to install our package dependencies for our api server so our dependencies are installed which means we should be able to do npm uh let's just try run dev first and we're up and running according to the logs our server is listening on port 5000 so that's cool for our api let's get out of here and go over to our ui app take a look in there same thing same thing will run npm install to install our package dependencies that installs completed so same thing let's check it out and see what happens when we npm run dev oh maybe that's not the right one what are our scripts um oh npm start is that right and so our ui is now up and running until i do this ctrl c to kill it which takes us to the next stage of our build to get these up and running i typed a command which tied up my session there and we really don't want to be in the business of making sure that we've got a logged in session running to keep our app alive so we need something that can start and run our application whenever we're home sleeping or out drinking beer here's what we're going to use for that we're going to jump over here and grab an app called pm2 so i was looking through this earlier let's grab this command jump back into our console here and install pm2 using the dash g flag which installs it globally and so now if we do pm2 that's up and working so we need to tell pm2 how to run this so let's take a look at our folder directory here and this is react so we need to actually build this into some static files so we're going to do npm build actually we'll do it correctly and type npm run build all right so our build completed let's take a look and i'll show you what it did if we do an ls listing again we now see that there's this build folder here and if we take a look inside that folder there's an index.html file and some a static folder that contains our javascript and all that kind of stuff in it so we're going to add this to pm2 we'll do that with the pm2 serve command build is the name of the folder where it's going to look for its contents 8080 is the port that i want to run it on and then dash dash spa just tells pm2 that we're running a single page application so we do that and it's up and running now it's time to go take care of our api so cd.wac api clear this out to get our node server up and running in pm2 we need to take a look at our package.json file and oh check this out they've got a pm2 command in here for us huh never seen anyone do that let's try that though let's do npm start i'll probably need to do npm run build first and i jump to that conclusion because we can see right here it's looking for the build folder with index.js file so we'll do npm run build that seemed to go fairly quickly which has me doubting whether or not it worked so let's try npm start again hey it worked check that out so let's clear this out and now let's take a look at pm2 status and we've got both of our applications up and running if we want to take a look at the logs for one we can do pm2 log and we've got our id right here for each application so let's take a look first at our api logs with the one and that looks good and we can do the same thing for our front end app and that looks good so as far as we know pm2 is up and running and it's managing both of our node applications but here's the thing if this server reboots it's not going to restart pm2 so if we take a look at the pm2 documentation here there's a pm2 startup command that's going to help us get around that so we'll do this we'll type pm2 startup and check this out it took a look at our net system found out that we were running systemd and it says to set up the startup command or set up the startup script we just need to copy and paste this command so i'm going to copy that but now here's the deal to create a startup script on linux you need root privileges which we've intentionally not given to our node user so that someday whenever this server is compromised whoever compromises it compromises it only has access to the things that node can do they won't be able to escalate up to gain root privileges so we're going to log out of our node user here back as the ubuntu user which does have sudo privileges so i will paste that in and we're all good so i want to go back into sudo su node again real quick pm2 status tells me that both of those are up and running but i need to tell pm2 when you restart be sure and launch both of these applications and we'll do that with the pm2 save command and we are all done with the node portion of our setup so log out i'm back as ubuntu we need to now install nginx we're going to do that with first running an apt update to grab all of our latest packages once that's done we'll do sudo apt install nginx that's done so we should be able to do sudo system ctl status nginx and that is active and running which is good that's real good man so that gets installed into the etsy nginx folder and if we take a look i think inside conf d there's nothing there um so let's take a look in sites enabled let's see and this is one of the places where you're going to find differences in nginx because ubuntu and the debian tree of linux handles it differently than the red hat family does so this depending on which os you're actually using it may be a little bit different yeah that's the file i want all right so we're going to edit this file we'll do sudo vim etsy nginx sites enabled default because we're just going to edit the default site and let's just do this on port 80 to get going and this is set up to use the static files that came with nginx so we're going to get rid of this tri files line here and instead we're going to do what's called a proxy pass so proxy pass tells nginx to act as a reverse proxy meaning whenever something comes in just give it to this other dude they know what to do with it the other dude in this case is going to be http localhost port 8080 which i think is what we ran our nodejs ui on then we're also going to add another location directory here location slash api is that how we want to do that let's try and see and here we're going to do proxy pass for our api servers that will be http colon slash slash localhost port 5000. and then close that bracket and then also i need to terminate both of these statements with a semicolon because i always forget to do that right quit and then we'll do sudo system ctl reload nginx and well it's that time let's see how i did here so i want to grab this ip address switch switch over to my browser do http colon slash slash oh look at that all right let's get back in here and sudo su [Music] to our node user clear this bring it down pm2 status and let's do pm2 log for our api and let's create an account username will email that's my email password ah thanks one password but we're not doing that all right so our front end worked ah i know what we didn't do in our source config constant.js file we needed to tell the application where our api server is so let's go do that source nope what was that file called yeah config well that path doesn't match let's take a look at this anyways ah all right so the docs are wrong but we'll get around it so right now it's set to localhost port 5000 slash api which you might think well that's exactly where it is which yeah sure it that's where it is from the context of this server but whenever i open my browser and i browse to it at this ip address that javascript downloads into my browser and executes from there and so from the context of my browser that api is not on localhost it's actually on this ip address so one thing we could do is we could change this to the ip address but that's only going to be a short term resolution instead let's do um demo dot w adm dot io slash api which means we need to set that dns up right we also need to do an npm run build while that's doing its thing i'm going to go into my dns add a record for it grab that ip address paste that in thanks for being helpful chrome but that's not what i'm looking for we'll save that our npm build finished so let's do a pm2 restart zero just to make sure it picks up those changes and then we'll do pm2 log one so we can see those logs come in hopefully let's actually just try this real quick demo dot w8n dot io slash api all right so the api didn't work our front end works that's sweet which means all right so take a look at this we did demo slash api and we got cannot get api that's and uh when we look here we don't see any connections in our [Music] um api server which means we've got nginx not routing that so let's get out of here go take a look at our nginx config i think that might be a problem i forgot the trailing slash let's try and see sudo system ctl reload engine x nope same thing all right all right did a little digging turns out nginx is configured correctly as we wanted it to it's just that this is not a valid route so if we actually do api uh users slash test me we get a success message here and so now if we go back to our ui at demo.w8n.io i can log in close one password and here's our dashboard up and running on our url um yeah let's take a look at one last thing here oops except let's not log all the way out let's go into etsy nginx into our default site so if we wanted to set up ssl on this which you absolutely do i'm just not going to do it here because this video is already running long and it's a demo server that i'm going to tear down as soon as i'm done recording what you would do is just uncomment this line listen 443 on ssl and they're not showing us everything here because you need to also add your ssl certificates so right here you can see actually let's blow that up so you can see so we would enable our listening on 443 and then add our ssl certificate and our ssl key for that domain name and then restart the server and you would be wrapped up and running on ssl so now this setup is fine i mean really it's fine if you're just launching your startup or just getting started i would much rather see you do this than go and spend a bunch of time building something else right because this is going to get you up get you running and get you customers logging into your system which is exactly where you want to be in a startup type scenario but there are some ways we can improve on this for example we typed a bunch of commands into the terminal and configured a lot of stuff manually so if anyone comes in and changes that how do we actually know what they changed so we could do backups right and now we've got to do backups every time we deploy new code which puts us in the business of managing the lifecycle of backup files which again doesn't drive your business forward for a small environment like this we could take on some type of infrastructure as code tool whether that's ansible or terraform or any one of the other multiple tools that could maintain our configuration for us but again in a small environment like this that's taken on a lot of technical overhead and puts you in the business of building and maintaining servers instead of building and deploying your application for your customers to see if you can gain traction with your application again i don't think that's a good use of time now this also isn't very scalable granted you know on a small app like this we could put a bunch of users on this one little server without worrying too much about overloading the server but eventually that server is going to go down it's going to crash and we've got no redundancy there so if we wanted a second server you know we'd have to go to that whole manual process of building that again again not the business we want to be in for this type of environment and we also got to carry around our ssl search which always poses a risk because you've got to put them somewhere accessible one last thing so we don't have any ci cds so as you write code changes and deploy them you got to go log in and manually deploy them to this server and now that i've killed your buzz you got to be and like what dude what the hell well there are other deployment options that exist that i think are much better suited to this type of environment where you've just got a small application and you're just trying to get it out the door i'm talking about things like heroku and aws whether you're using aws fargate or potentially a serverless solution and you can also use kubernetes although again kubernetes is huge massive bad bad bad mistake for an application like this but here's what i'm gonna do because i really like this project and i think it's really cool i'm gonna go through and i'm going to redeploy this exact same app using all those different things i just described to you so if for no other reason you've hit the subscribe button hit the subscribe button now so that as i start releasing these videos you'll see them and you can see this exact same application deployed in a bunch of different ways and learn the differences between those which ones fit which environment better and we'll do that meanwhile if you want to start like game prepping for that be sure and check out the devops roadmap guide at devops4developers.io slash roadmap it's got a bunch of things that tie to the steps that we took here today and it also addresses some of the concerns that i raised here at the end of the video and kind of sets the stage for some of the things we're gonna have in the next few videos so check that out and um yeah thanks for watching and i'll see you in the next video
Info
Channel: DevOps For Developers
Views: 11,549
Rating: undefined out of 5
Keywords: nodejs, linux, nodejs tutorial, node js, learn nodejs, nodejs beginners, nginx, pm2, nodejs best practices
Id: cLZkCqYgxKA
Channel Id: undefined
Length: 29min 59sec (1799 seconds)
Published: Mon Mar 21 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.