 Hey, welcome everybody. In this video, we're going to deploy a Next.js project on a virtual private server. We'll use the power of GitHub Actions and leverage the GitHub Action Runner to establish continuous deployments triggered by GitHub Code Commits. And I almost forgot to mention that in this video, we will install the latest Node.js version and use PM2 as a process manager under a separate user account. Then we will install and set up NginX so we can reverse proxy to our Next.js website. And finally, we'll point a domain name to the server and set up SSL certificate. Before we get started, I wanted to try and draw a very basic diagram of what is going to happen in this video. And I've already changed the diagram like a million times where hopefully this one will be okay. So essentially, in the first step, we're going to be creating a very basic Next.js application. From there, we're going to use GitHub in order to have version control of our project. And also, it's good for collaborative software development. Now, when we create our project, each project will have its own actions. Action is the platform that is going to help us automate the software build. So we are literally going to make a list of actions that we want to do in order to be able to build our project. Now, in order to publish your website, we need a web server. In this case, in order to host the website, we're going to have an Ubuntu server. Now, in order to connect to a Ubuntu server with our GitHub project here, we're going to install a GitHub runner. This runner is basically going to be installed on Ubuntu server. And it's going to allow us to talk to our project and then do the actions. You will see in the video that when we connect our runner to a project, we'll be able to see whether the runner is idling or offline inside our project here on GitHub. So that's how it's going to work. And the last step would be here, a user makes requests. And here, we're going to be using engine X to reverse proxy to the server and wrap the website from port 3000. And when this step is done, basically, the user gets a response. And that's it. I hope that you find this diagram useful and enjoy the process. Hey, welcome everybody. And let's get started. So for today's video, we're going to be using github.com in order to do the continuous deployment. If you haven't yet, go to github.com and sign up for free. I've already logged into my account. So I'm going to go to the dashboard of github. So a little bit zoomed in. And then from here, we need to create a repository. So let's click new. Let's give it a name. I'm going to choose ruddy-vps as virtual private server. For the description, I'm going to leave it empty. And my repository is going to be private. I'm not going to create a readme file because next.js comes with one. And then for the gitignore, we're going to select node because we don't want to be uploading all the node files onto GitHub. And the last thing that I'm going to choose is the license form project. And this is going to be MIT. Let's click create repository. And here we have a brand new project for this project. I'm going to be using github desktop, but feel free to use the command line if you wish to push and pull your project manually. And if you go to desktop.github.com from here, you should be able to download it for Windows, macOS. And I believe that there is also a version for Linux if you wish to try it out. It's nice to have, but you don't need it. You can just use the command line if you wish to. The first thing that we need to do is if you don't use the github desktop, just make sure that you clone the project locally so you can work on it. In my case, I'm going to go on github desktop and from here on the drop down menu, click on it on the add drop down menu here, click on it one more time and then select clone repository. Let's find the repository that we just created. So ready dash VPS and let's select it. And I'm going to save this in c drive github dash applications ready dash VPS and clone. If I open this in the explorer super quickly, you should see that I have exactly the same files inside here as the ones on my GitHub repository, which means that I've successfully cloned the project. And now we can create a brand new next.js application. I need to create the next.js application inside this folder. So I'm going to do left shift right click, open in terminal. If you're using mac or linux, you can just cd to your project folder where you wish to create it. And now we need to create own next.js project. So npx create dash next dash app at latest. And in order to create the project inside this project folder, I'm going to do dot slash and press enter. If by any chance you missed this last bit, and it creates a new folder for you, you can always grab the files and put them into ready VPS, but you might need to install your modules one more time. Would you like TypeScript for this project? I'm not going to be coding anything. So I'm just going to put the default options in here that I have. So TypeScript, no ESLint, no Tewin CSS, yes, source directory, yes, app router, yes, import alias, no. And that's it. As you can see, the project is being created in this folder, which is great. But as I said, if you created a new folder for you, just grab the files, paste them inside here and just do npm install to install the modules and you should be good to go. Let's test the project super quickly. So I'm going to do npm run dev and let's copy the URL. And as you can see, our project is now working on the port of 3000. I'm going to open this super quickly in Visual Studio Code. So left, right click, open in terminal. I'm going to do code period, enter. And this will open Visual Studio Code with the project on the left side here. Now the only thing that I'm going to change inside the project page is this here. Instead of this, I'm going to put by Ubuntu and say, so hopefully this should refresh by Ubuntu and we get to go. Anyways, this was just a quick test to see what everything is working. Now the real reason that I opened the project in Visual Studio Code wasn't to change the logo here, but to talk about the .env file. So normally your project will have a .env file where you store all your secret keys and so on. So I'm going to put .env.local and you want to be able to add all of your variables inside GitHub. I'm going to create a new one next underscore website URL and this is going to be equals HTTPS slash slash and then website.com. Maybe this is something that you're reusing throughout your entire application. Obviously you probably have secret keys and you want to be able to upload them on GitHub. Uploading the actual .env file is not safe to do, especially if your project is public on GitHub. You don't want to do that. And I'm going to show you how we can transfer them. But first what I'm going to do is go to the GitHub application here and then push the changes. So I'm going to do init as initial deployment and then commit to main. Push origin and they should push absolutely everything except the .env file. So if I go back to my GitHub page and refresh, you should see that we have the next .js project in here without the .env file, which is exactly what we want. Normally the .env file is ignored by this file here. So now let's have a look at how we can transfer all variables. If we go to settings and here on the left side, you should have secrets and variables. Click on this and then click on actions. From repository secrets, we need to create a new one. So click new repository secret and we need to give it a name. So in this case, we basically grab the next underscore website URL and we paste it in here and no secret goes inside here. So I'm going to copy my secret and paste it. Okay. If I add the secret, you will see that or variable name is now here and you should be able to use this variable name now throughout your project. And one thing that I wanted to show you is that if you go here and edit this secret, so I'm going to edit it, you will see that the value is now gone. So you can definitely update your value. You can create a new one, but your initial value is gone. And this is obviously for safety reasons. So that's all good. And if I go back, we have all secret key. I didn't update it. All good. Let's go back to code. The next step would be to create or virtual private server. For today's tutorial, I'm going to be using digital ocean and the service that I'm going to be using is in the products and then compute and it's called droplet. So if you click on this, it basically allows you to create a VPS virtual private machine that is also scalable. Now we are going to be using Ubuntu in this tutorial, which means that you can pretty much do this on any other provider that you wish. You can use Amazon, you can use a Raspberry Pi if you wish. Whatever you like, feel free to shop around, see what's best for you and your needs. And you should be able to follow along as long as you use Ubuntu. If anybody decides to use digital ocean, I would appreciate it if you'll use my link below. This is not sponsored in any way. It will just help me a lot if you use my link below. That's pretty much it. Now let's log in. And here on the left side, you should see droplets. So if you click on droplets, click create droplet. From here, select your region that you wish. I'm going to choose London because this is the closest to me. From choose an image. There is a big marketplace that you can choose images from. But today we're going to be using Ubuntu with the version of 23.10 NX64. Let's scroll down, choose size. I'm going to go with shared CPU, which is the cheapest. And then if we scroll down a little bit more, for the CPU options, I'm going to go with the regular this type SSD. This is going to give us even cheaper options. And the one that I'm going to use is the six dollar per month one. And this is actually fitting in the minimum Ubuntu requirements, which are one gigabyte of CPU, one gigabyte of RAM and 2.5 gigabyte SSD. So this fits as of minimum. But if you use another provider and there is a cheaper option, I wouldn't go through it because you might struggle. So definitely go with something like this or bigger, of course, if your project requires it. So let's go down a little bit more. And from here, we need to choose authentication method. Now the easiest method would be to go with password. You can just select the password and you can log in with root using SSH. Now the problem with passwords is that they can be brute forced. And technically speaking, you might be able to restrict your IP address from the networking tab in here. I haven't tried it, but you're most likely going to be able to do that. But the safest option here is to go with an SSH key. And I'm going to show you how to set up this. So it's up to you which way you want to go. I'm going to do SSH key. And I've already got one inside here, but I'm going to create a new one. I'm going to click new SSH key. And then from here, we need to follow the instructions. So here on the right side, it says follow these instructions to create or add SSH key on Linux, macOS and Windows. Windows uses without open SSH can install and use putty instead. Let's follow the instructions. So I'm going to copy the SSH key gen here. And we need to open a terminal, PowerShell, whatever you have. So I'm going to open the terminal here. And I'm going to paste the command to generate a new key pair. So right click SSH dash key gen, press enter. And this is going to generate the public private RSA key pair. And you can name them if you wish. But I'm going to leave the default name which is ID underscore RSA, press enter, give it enter a passphrase, I'm going to put my name ready and press enter, ready and press enter. And this should generate a nice art for you which you can print and attach to your wall jokes aside. Let's go up. And you will be able to see that your identity has been saved in see users range dot SSH ID RSA. So I'm going to copy this. So obviously if you're Linux or Mac, it's going to be different. But I'm going to copy this, go to my PC and paste the inside here. And we need to search for SSH. And then here the private key and the public key. The public key basically has dot pop at the end. And that's it. So let's open this and let's copy the code from here, the entire thing. And let's close it. Let's go back to the website here and paste or public key. I'm going to paste them. And for the name, I'm going to say Radis desktop PC. And then I'm going to add the SSH key. Now that we've added the SSH key, let's scroll down and they say we recommend these options. I'm going to click on the add improved metrics monitoring and alerts because it's free. And then feel free to choose whatever else you need and scroll down a little bit more. For the house name, I would strongly suggest you that you change this. So I'm going to put ready at least to know what it is because when you create multiple droplets, it will get confused in which one is which. So definitely give it a name. Give it a few tags, which will make it easier to find. And that's more or less it. Let's click create droplet. All right, this should take 20 to 30 seconds. And I'll be back. Okay, or virtual private server has been created. And if you click on it super quickly, and inside the dashboard, you should be able to see your IP in here, which you can use to SSH. Now one thing that I would suggest you do is to reserve an IP. And the reason for this is because if you ever need to power down this instance and create a new one, you can quickly detach the reserved IP and attach it to your new instance. So that can be quite helpful. And if you do it, I would suggest you to do it now. So I'm going to enable it. And I believe that it's free. I don't think that it costs anything. So I'm going to assign reserved IP. Okay, or IP has been assigned, as you can see, it's still doing it. But if I click on droplets and click on my droplet, you should be able to see that we now have the reserved IP in here. Let's copy the IP and let's open the portion. So I'm actually going to be using this portion here and just clear everything. Let's try to connect to this IP to a server using SSH. So in order to do this, do SSH, and then root is the username that we want to connect with and then add and we paste the IP in here. Now, if you want to see what's going on behind the scene, you can put dash V and this will show you everything that's happening. So I'm going to press enter. All right, I'm going to type yes, press enter, enter passphrase, that's ready. Enter. And as you can see, we are now inside or Ubuntu server using root and then ready Ubuntu and so on. Also, this has been added to the to the known host. And next time I try to connect, it won't be asking me any other questions. So if I was to close this, and if I do right click, open in terminal super quickly one more time. And if I do up, this is going to be SSH root at the IP, press enter. And then it's going to ask me for the passphrase ready, press enter and we are in. All right, before we start setting up or Ubuntu server, if you haven't managed to log in by any reason, obviously, maybe pause the video, try to see what's going on, you can put dash V after the IP in here to see what's going on. But also there is another way. So the other way would be to go in your droplet and the actual droplet has a console on its own. So if you click on this, it will open the console. And you'll be logged in as root. Here we go, connected. And it will be exactly the same as if I was to SSH from my computer. And you can continue using this as well. If you wish to, it's really up to you. So this is definitely an alternative way of doing it. I'm going to close this, I'm going to close the SSH folder, as we won't need them. And let's open the connection to a server. All right, the first thing that we need to do is to update the outdated packages and dependencies on our system. Do sudo as super user do, and then apt update, press enter. And this should take a couple of seconds to get the latest packages. Now we need to do sudo apt upgrade dash Y. And this is going to build everything on our server. We just need to press enter. And then okay, one more time. Perfect. The next thing I'm going to do is create a new user. And the reason I'm doing this is because at some point in the future, you might end up having multiple users, and you might want to have different Node.js versions, whatever, you might want to be able to install different package versions for specific user. I'm going to clear this just so you can see a little bit better. And then to add a new user instead of root, we can do add user. And then the username goes in here. So in my case, I'm just going to put ready. This is the user that one had. And the user has been created. We need to put a password for this user. I'm going to put my password of password. I'm retype the password of password. Okay, everything is looking good. Full name. I'm just going to put ready. Dev, press enter room, room number. All right, from here, I'm just going to press enter. I'm not going to feel any of this information. And then is this information correct? Yes, press enter. And we have the info added to the ready user. One thing I'm going to do now is to add this username to the super user group. So I'm going to do so we potentially won't have to do sudo on every command that we do. But if you have a struggle to install something, if you don't have the permissions, you can always do sudo and then do the command. So in this case, let's try this user mod ag and then sudo and then the username of ready, because we're still using the root username, although that we created a new user, we're still using the root username. And basically the option stands for pending this user to the super user do group. And the G flag basically stands for group, which group do you want to add this username to? And the group that I want to add it to is sudo. That's pretty much it. And press enter. If we do PWD, PWD, you should be able to see that we're currently using root. And now this is very important. We need to switch to the newly created username that we created, which is ready in this case. So in order to do this, you can do sudo, switch user su-ready. And now you'll be able to see that we're getting ready at ready Ubuntu and the rest. So before it was root and now it's ready. This is going to be important because when we run on Node.js, we want to be running it from ready later on. Otherwise, the GitHub actions might not recognize the process. I'll show you later on. All right, this is all looking good so far. If we do LS, let's see where we are. It doesn't really show anything. All right, since we're still on the server, I think it's a good time to install the packages that we need. So I'm going to clear this one more time, just so you can see a little bit better. Okay, now let's install the first repository, which is going to be Node.js. In order to do this, let's first of all do sudo apt update. One more time, the password for ready is password, press enter, and this is going to do the updating. The next thing that I want to do is to install the latest Node.js. Now, if we go to the browser super quickly, the great thing about digital ocean is that they have articles for pretty much everything. And if you scroll down on this tutorial super quickly, maybe I can paste this somewhere as well. So you have it. But basically, you have a couple of options to install Node.js. And the one that I'm going to be using today, which I found the easiest was this one here. So using the Node version manager, this was the easiest one I found. But to be fair, I think they're all equally easy. So what I'm going to do is copy this line of code here, paste it. And if you wish, you can post the video and copy the URL and press enter. Let's go to the second line here. I'm going to copy it and paste it. Okay. And then I'm going to go to this line here, copy, paste. Let's go to the next one, copy, paste. And this is going to list all of the Node.js versions that we can choose from. As you can see, which is amazing. And now we need to choose the one that we want. And I believe that with Node.js 14 app router, the minimum was around 18.7, I believe, maybe around here. But obviously, I want to use the latest one. So what I'm going to do is like this. Currently, on my PC, I'm actually using this one here. So I'm going to do the same VM, install and then the version. So V 20.10.0, press enter. And this will install Node.js first. Now let's do NVM list. And hopefully, you should be able to see that the default Node.js version is now set to V 20.10.0, which is awesome. Now let's install PM2. I'm going to clear this. Let's go back to the browser and search for PM2 in Google. So PM2.keymetrics.io. This is actually great. It's basically a Node.js process manager. And it's super easy to install. Basically, I'm going to copy this. But let me show you super quickly what you can do. Essentially, you can run multiple applications on your server. And they have a lot of like really cool interfaces that you can use, such as this one here to monitor your processes. The commands are very easy to use, like list your command, your processes, stop, restart, delete, and so on. So this is what I'm going to be using. There is probably, I think that there is a paid version for it, but we're going to be using the free version, which is absolutely fine. I've been using it for a while and it's awesome. So let's go back and let's do right click. So MPM install dash PM2 G and dash G for globally. I'm going to press enter. And this should take a couple of seconds. All right, now that we have everything that we need, let's go back to GitHub and create our application runner. So I'm going to close everything here and go back to GitHub. All right, the next step would be to set up an action runner. So if we go to actions and then runners, and then here we should self hosted runners. If you click on this, let's click on new runner. And now we need to create a new self hosted runner. And from here, we need to choose Linux 64 architecture is fine. And we need to run the following commands on our server in order to be able to connect GitHub to a server and then do the continuous deployment. Okay, so I'm going to zoom in a little bit. In fact, I'm going to put this on the right side. All right, because the menu is not collapsible, I had to put this at the bottom. But essentially, this we're connected to or server using ready. And we need to follow the instructions from here. So where it says download, let's start copying. So this is going to create a folder for us. MK the actions that runner CD actions runner, press enter. And we are inside this folder here. And now we need to download the latest runner package copy, right click to paste it, press enter. This should take a couple of seconds. Now we need to validate the hash. Let's copy, right click, enter. Here we go. And now we need to extract the installer, copy, right click, enter. Perfect. Let's scroll down to the second bit here, which is configure create runner and start the configuration experience. So I'm going to copy this, right click and paste it. As you can see, we're getting authentication. Enter the name of the runner group to add this to runner, press enter for default. I'm going to press enter and the name of the runner. Okay, press enter. Enter additional labels. I'm going to press enter to skip and runner successfully added and the name of work folder. I'm going to try to put this as default as well. I'm going to press enter. And we should be good to go. And now the last thing that we need to do is to run it. So potentially if I do LS, you should be able to see that we've created a lot of files here. And we need to just run this run dot SH. So I'm going to copy the command and right click to paste it run dot SH. Connecting to GitHub. Everything is looking good. Connect to GitHub. Yep. Listen for jobs. Perfect. Now one thing that you might want to notice here is the second step here. Using your self hosted runner. When we create or YAML file, we need to put this runs on self hosted, which I will show you. Okay. One thing that I wanted to show you about the action runner now that we've connected there to GitHub. Let's go back to GitHub super quickly. Click on settings. And then here under actions, you'll see runners click on that. And then you should be able to see your server inside here and the status should be idling. If I was to close this control and see and now the runner has stopped running. And if I was to refresh the page here on GitHub, you'll be able to see that this is now offline. If we ever need to restart the server, I want this to be able to restart as well. So we don't have to do it manually. So I'm going to do control and see to exit this. If we do LS dash one, we can see all the files inside this actions runner folder. So the first command that we need to do is sudo svc dot SH install present password for ready was password. Okay. Now if we do sudo dot SVC dot SH and then status, you should be able to see service enabled, present enabled, active inactive debt. Okay, that's cool. And now we can do sudo dot slash SVC dot SH start. Okay. And now as you can see, we should have active, active running. And the last thing that we can do if you wish to, you can stop it by doing stop instead. But we don't want to do that. So let's leave it as it is. Let's go back to the browser here refresh, make sure that this is idling, which is great. From here, let's set up or workflow, click on actions, search for nodes. And the one that we want is this one here, node.js by GitHub actions, click configure. And then let's remove the comments because it's already hard to see inside here, but I can't zoom anymore. And let's have a look into this. So the first thing that we have here is the project name. I'm going to leave it as default. And then the second action here is on push. So when push changes to a GitHub project, essentially it's going to run everything else. And as you can see, it's looking for the branch main. You can also make different branches such as development, prediction and so on. And when you push change to them, you can deploy your project. In this case, I'm going to be using the main branch. So every time I push changes to the main branch, it's going to run the rest of the file. And for pull requests, I'm going to remove this because I don't want anything to happen when I do pull requests. So let's move that jobs built runs on Ubuntu. Earlier when we set up the action runner, the instructions there were to change this to self hosted. So let's type self dash hosted. This is important. And then for the strategy matrix NodeJS version, we need to select the NodeJS version that we installed earlier in this tutorial based inside here. Let's remove this comment as well. We don't need it. We can also pull the EMV variables here. So by doing EMV column here is where we can list all of our EMV variables by using the name. So in this case, dot EMV variable was called next website URL. Here we go. And then the value you do column and then the value can be taken from GitHub by doing dollar sign, curly bracket, curly bracket, C dot, and then the variable name. So next underscore website URL and then close this with the two curly brackets. And this comes from settings, put this on the little tab. And then this is going to be on the secrets and variables actions. And it comes from here. So the value is going to come from here. What else do we have? Okay, so we have different steps and everything else in here is absolutely fine, except we don't want the test for testing purposes. All I want to do now is run those actions, build the project and don't do anything else. We'll come back to this later on, commit changes, put whatever you like and commit the changes. If we go to actions super quickly, you will see that we already have a workflow running. So if I click on it, this might take a while, but if I click on it one more time, hopefully click, click one more time. Here we go. So this is what I was looking for. So it's going to start the jobs, it's going to run the actions, it's going to use the note version that I set up manually, and then it's going to continue doing the rest. Okay, I might have to speed up this part because it will take a while. Okay, and our first build is complete and it's done in one minute and 37 seconds, which is awesome. If we pull this, fetch everything, pull everything. And if I go back to my project and click on GitHub workflows, Node.js, YAML, essentially we got up to here where we built the project. And if I do ls to list all the files and do dash one, this will list all the files line by line. When we created the actions runner, we created a work folder here, which is where our project should be. So if I do cd underscore work, and then let's do ls one more time, dash one, we have pipeline mapping, actions, temp tools, and then we have ready vps, which is awesome. So this comes from GitHub. If I do cd ready dash vps, this should be our project. If I do ls dash one, I don't fully understand why it does two folders, so ready dash vps and then ready dash vps. Not sure why, but we need to go one step further. So right, so cd ready dash vps press enter. And now if you do ls dash one, you should be able to see all of your project files. So we have the tailwind config, the source, the public, the packages and so on. If I do cd source and then ls dash one, you should be able to see app. And then if I do cd app, and then dash one, oh, cd app, first of all, and then ls dash one, you'll be able to see father conglowers, layout page and so on, which is exactly the same as all project or project has been built. And finally, we should be able to run this project. Okay, let's clear this and let's see the back to this folder here. So cd backwards ones, cd backwards one more time. Here we go. So as long as you're in the project folder, and if I do ls one more time with one, this is the project folder. So from here, we need to start a new process. Just like you do npm run depth, we need to start the website, which normally is npm run start. So if I go to if I go to package.json, you'll see that we have next start. So we need to run this script inside or bone to server. So website is running, and it's probably going to run on port of 3000. In order to do this, we're going to be using PM2, which we installed early in this tutorial. So we're going to do PM2 start npm dash dash, which is going to give us an option of doing name. Unfortunately, it goes on another line because there is a lot to it. Let me do that. Okay, that's a lot better. I think. And now we can choose a name for the process. In this case, I'm going to call it next, js, close this, and then we can do dash dash start and then dash dash watch. Let me zoom in back. Here we go. That's what we need. Another press enter. You will see that PM2 started. And we have a newly running process here. It says that it's online. Watching is enabled, which means that if the server for some reason crashes, it should restart automatically. And it's using the user ready, which is great. And yeah, that's pretty cool. If we go back to our instance here, and if we click on our reserved IP, and if we go to the browser and type the IP and then port of 3000, press enter. As you can see, our project is working, which is great. Now there is one more thing that we need to do. First of all, if I restart the server, this process will most likely stop and we'll have to do it manually. So we don't really want that. You might want to restart your server at some point, and you want everything to run seamlessly and just to work. We can do PM2. Let me zoom in and then startup. Press enter to set up startup, copy paste the following command. Okay, so we need to copy this command. Copy right click to paste it. Press enter. Password for ready was password. Okay, that's looking good. And now we want to be able to freeze this process. So on reboot, it will start. So freeze the process list on reboot via PM2, save, press enter. Saving current process list successfully saved in ready PM2 dump dot PM2. That's pretty much it. All right, now if we do PM2, we should be able to see the process that is running. So now let's try to shut down the server and see whether we get the service, the action runner working and also let's see if we get the PM2 also working. If I go to the browser super quickly, you will see that the website is working. And now let's shut it down. Shut down and failed to schedule shut down. Okay, maybe so do shut down. And here we go. The system will power off in literally one minute. And then we'll see how this goes. So if I refresh on the website now, it's still working. I'll wait a second. And then I'll refresh in about a minute to see what's going on. Okay, the server should be shutting down, even the processor, even the CPU changed here a little bit. So if I refresh, okay, so the server is now down is switched off. The website will not work. Here we go. It's already should just go blank in a second. And then our action runner here, if I refresh is also offline. So now let's put the server back online. And this should take a probably like 30 seconds or so to start all the services. And I'm hoping that the PM2 will start automatically and the website will work. And also I'm hoping that the server worker here will start automatically without us having to do anything else. So let's wait and see. All right, let's try to refresh this. Maybe it's already done. Okay, we're still offline. And it's idling. Okay, it didn't take long, maybe like 30 seconds. And as you can see, the runner is idling, which is amazing. And now if we go back to the website, the PM2 is also working. So the process is also working. But we should be logged out from the console because the server closed the connection. Okay, awesome. Let's clear this up. And let's reconnect to the server by doing SSH route and the IP address. I'm going to put my passphrase. I think it was ready for me by center. And I'm already back on the server. All right, now, technically, everything is working here. If I was to change something on the project, let's say we go to the page, get started by editing. So I'm just going to say, hello world. Our local host is gonna restart here. And if I do super quickly, local host of 3000, you will see that we're getting hello world and some other stuff in here. Maybe I can just remove this code. Here we go. Just so we get hello world on its own, and we have hello world. Okay, now if I was to push this to GitHub, let me go to the action super quickly. Here we go. This is the first action that completed. But if I was to push this code to GitHub, this change, say, updated home, and then commit to main, push origin should take a second. And now if I go back here, I probably need to refresh. And here we go. This has picked up the new job, which is updated home. And now it's going to go through the entire process of building the project. Here we go using Node.js, running the project and so on. So this should take again, probably like a minute to do. And then we'll set up the rest of the project. Okay, perfect. Or second build was also completed. But now we need to change one more thing inside here. If I was to go to the project and refresh, you should be able to see that we're getting the latest changes. And this is the live website. Now one thing that we do need to change here is inside or Node.js, JS, YAML file, where we have NPM run built. We also want to add one more line. And this is so or PM2 process restarts or starts the project. So if I do PM2 list, you will see PM2 list is because, okay, this is a good thing, actually, I'm logged in with root. And that's why I cannot see the PM2 list. So I'm gonna have to switch users. So let's do clear. And let's do pseudo switch user to dash ready. And now if I do PM2 list, we should be able to see all the current running processes. One important thing is that when we push changes, we want to select this process here and restart it. So this process has an ID of zero. So in order to do this, we can go here and then do dash, run and then PM2 restart. And we restart the process of zero, like so we want to do that. But also in order for this to work, because we can only run the command PM2 inside the project directory, we will need to find the project directory and change the folder. So inside here, I'm going to do name and then say change directory. And to change the directory, we can do run CD. And then we change the directory from here. And it's going to be home, I believe slash ready slash action runner dash. And then the website name. So let me have a look because I actually don't know the full thing. So I'm going to do right click. Can I not do that? Okay, so now let me do that. So let's do CD slash home slash ready slash action runner actions runner press center. And now we have the work directory. Okay, so it's going to be CD underscore work. And then we have the ready VPS ready VPS. Okay, so let's do that. So this is actions runner and then underscore work and slash ready VPS slash ready VPS. And now if I do this, let me try to paste it. Here we go. And now we should be in our project directory. And if I do this, this is where our project is. And this is where we can restart the PM process. So when we CD to this project folder, we should be able to run mp to restart in order for this to happen. I would definitely suggest that we push this. And then we wait to see what happens. So I'm going to push this change to restart process, PM to restart process zero. I'm going to definitely commit this and retest everything just to make sure that everything is working before we do the next thing. So I'm going to go back to the website actions here. I'm going to wait for this to happen. And then once we are done, we'll continue. Okay, the process is done. If I click on it, click on the job, click on build, scroll down to the bottom somewhere, it would say, Oh, here we go. PM run PM restart zero. And hopefully, yep, everything is looking good. If I go to the console and if I do PM to list, you should see that this is still working. Which means that all website is also still working. All right, the next thing that we need to do is to point a domain name to this IP, and then we can create the SSL after. So my domain name is located under porkburn.com. I'm going to sign in from here. Obviously, every domain name register will be slightly different, but the settings will be exactly the same. I'm going to select my domain name, which in this case happens to be ready dot lol. I got a really cheap for a year and then I probably won't renew it. But essentially, what we want to do is scroll down to the bottom and find the record. As you can see, I have two records here, which I want to remove. So I'm going to remove both of them, like so. Let's go to the top here where we have the record. I need to go back to my server here and get the reserved IP. So I'm going to copy this, go back to my domain name, and we need to add two records. The first one is going to be an address record or a record, and then it's going to be blank. So this is going to be basically ready dot lol. And then the answer will be the IP address. That's it. All we need to do is add it. And then this is going to be added here at the bottom. And also I need to add one more. So again, a record, but this time we're going to add an alias. It's going to be basically www dot. In fact, we don't need the dot because we've got it here. So we add in www and then the URL is there. And we just need to put the answer to be the IP address of a server again. Click add. And now at the bottom here, we should be able to see two a records. And sometimes the records might take a while to propagate. So that's something that you might want to check. And I'm going to grab ready the low and look for this IP and NS lookup search for NS lookup. Let's choose the first website here, but ready dot low find NS records. And as you can see, speak to digital ocean. And we have exactly the same IP as here, which means that it propagated in literally like no time, which is pretty cool. So I won't have to wait. It's already done. And of course, I can put www dot find records. And this is also propagated, which is awesome. If I go to the URL of ready dot, if I go to ready the low and press enter, nothing will happen. But if I go to ready the low of 3000, you will see that the website is actually working, which is pretty cool. Now let's set up a reverse proxy. So we don't have to do the port 3000. And we also set up the SSL. All right, let's go back to the command line and let's clear everything. And normally you will do exactly the same thing as in the beginning of the tutorial, do pseudo APT update. If anybody's tuning in now, put the password of password. That's for me. Okay. And now we're going to do pseudo APT. And we're going to install engine X, like so. Would you like to continue? Yes. And now to see the status of engine X can do system control by doing CTL and status. And then engine X press enter. And if you see this, everything is looking good here. Okay. Engine service, a heavy performer web server and reverse proxy server. If I was to go to ruddy.low and press enter, I'm hoping that we get welcomed, which is awesome. So engine server is working. And now we can just do reverse proxy to go to that port number. Okay, let's go back to the command line, clear everything. And from here, we need to create a custom configuration block. So we don't need the default directly. And in order to do this, we can do pseudo. And then we need to do nano nano is the editor, by the way. And this is going to be etc, etc. Engine X and then slash sites available slash available. And then the domain name. I don't know if you're able to see, I'm going to do this. And then the domain name is going to be ruddy.low in my case and press enter. This is going to open the editor. And then inside here, we're going to have to copy and paste a little bit of code. And feel free to post the video. Basically, we have a server which listens on port 80. And then we need to change the server name here to ruddy.low. And then www.ruddy.low. And this is very important thing that we need to change it here is the proxy pass app server address. So in this case, we are going to need to do localhost of 3000, which is where our next JS website is working on. And the includes proxy parameters you can check out in the folder, etc. engines proxy params. And then you'll have the proxy set headers inside there, which you can edit if you wish to. I'm not going to do any of this. All right. And now we need to do control X. And this is going to say, would you like to save the modified files, press Y. And this is going to save it as here, ruddy.low. As you can see at the bottom and press enter. And we should be good to go. So this file should be saved inside here. And now we need to enable this configuration file by creating a link from the sites enabled. There are actually that engines reads at startup. So see the LN dash s. And then the folder is etc dash engines sites available slash ruddy.low. And then we do, etc. Etc slash engines slash sites enabled. And then slash and then we press enter. Okay, that should be done. We can test the configuration file by doing sudo engines dash t. Okay. And we have an error. And I believe that we're going to have to open the sudo nano site available ruddy.low. It might be because I've put, I haven't put HTTP here slash slash localhost. So I'm going to do control an X. Yes. Press enter. And now if I do sudo engines dash t. Okay. Syntax is okay. Everything is okay here. So it was just the HTTP that I forgot. And the last thing that we need to do is restart. So sudo system control restart and then engines press enter. And now if I go back to the browser put ruddy.low. As you can see, our website is working. We are fellow world by Ubuntu here, which is pretty cool. And now we just need to install the SSL. So I'm going to go back to the command line here. And let's do sudo apt install, third bot, and then python, python free. And then third bot dash engines press enter. Would you like to continue? Yes. Okay. Let's clear this. And now we need to go to sudo nano, etc. Engines sites available. And then ruddy.low. Make sure that you have your domain name in here. I've already added mine. I'm going to close this with control and X. Make sure that you do sudo engines dash T one more time. Everything is looking good. And now we just need to obtain a search by doing sudo third bot dash dash engines dash D. And then ruddy.low is the domain name. And then dash D, www.ruddy.low is the other domain name. So press enter email address. Okay. So I'm going to put my email address, press enter. Yes. Yes. One more time. And now this is going to go and request certificates for ruddy.low and www.ruddy.low. And as you can see, the certificate was issued and it was saved on there, etc. Etc. Let's encrypt live ruddy.low and then full chain.pam. And yep, everything is looking good. Successfully deployed the certificate. Congratulations. You have successfully enabled HTTPS on ruddy.low and ruddy and the www domain name. So if refresh automatically, as you can see, this went to HTTPS. And now we have a valid certificate, which I can see here. Connection is secure. And I'm not and here we go. Certificate is valid. If I click on it, should see somewhere on here. But but yeah, that's pretty much it. And just to test everything one more time. Let's go back to the project. Let's edit the page. And let's put hello world v1, for example, save this. And if I go back to GitHub desktop, and if I commit this push, it's going to take a second. And if I go back to GitHub here, let's see the actions, you will see that we're getting update page.js. This is obviously going to take some time to build. And hopefully, after this is done, we should be able to go to our domain name and see the change of our website. And that's going to be it. Okay, and our build is completed. So if I go back to the website here, ruddy.low, we should be able to see hello world with v1 refresh, hello world with v1, which means that everything is now working correctly. If I was to reboot the server, everything will restart and your application will just start as soon as your server is ready. That's pretty much it. It was a tough tutorial to do because there is a lot of variables around. I hope that you find it useful. Consider liking this video and subscribing to my channel. And hopefully, I'll see you in another video. Bye.