Python Django Tutorial: Deploying Your Application (Option #1) - Deploy to a Linux Server
Key Takeaways
This video tutorial covers deploying a Django application to a Linux server using Linode, including setting up a new server, configuring SSH access, installing software updates, and deploying the application using Apache and mod_wsgi. The tutorial also covers security best practices, such as disabling root login and setting up a firewall.
Full Transcript
Hey there. How's it going everybody? In this video, we're going to be continuing the Django series and learning how to deploy our Django application to a web server so that anyone with internet access can use it within a browser. Uh, so far we've created this application with some good functionality, but the site still only lives on our local machine. Uh, right now this is just running in my browser on my local machine, but no one else can access this. So, the point of building these sites is to deploy them so that they're accessible over the internet. Now, look, I'm not going to lie to you. Uh deploying is a bit tricky. Uh you can find a lot of Django tutorials online, but not many of those cover deployments, and that's because they can be difficult. Uh it can be overwhelming because there's a lot of different ways to deploy an application, and it's hard to know what's best for your specific application. Uh so we're going to look at several deployment options in this series. So we'll look at how to deploy to your own Linux server, how to deploy to Heroku, how to deploy to Python anywhere, and possibly some others. In this video, we'll be learning how to deploy our application to our own Linux server. So, when you deploy to a Linux server, you're most likely going to be deploying to a virtual machine that is hosted by a company. So, that's going to be a company like Lenode or Digital Ocean or AWS. Uh, I personally use Lenode for my own web applications. So, that's what we're going to be using in this video. Uh, and Lenode was actually kind enough to sponsor this video and has provided me with a link where you can get $20 of free credit towards an account. Uh, so if you want to follow along with this video, then I'll leave that link in the description section below where you can sign up for an account and get enough credit to follow along. So I've been using their services for my own personal website for years. So I was really happy when they contacted me about sponsoring a video. So with that said, let's go ahead and get started. Um, okay. So like I said, we're going to be deploying to a Linux server. So, this method of deployment actually takes the most effort to set up, but is also the most flexible in terms of what control you're going to have over your application and web server. So, in future videos, we'll look at deployment options that offer some free tiers, but they usually only offer basic services. So, for example, if you want to use your own domain name, such as myjang blog.com or something like that, then you'll have to upgrade to a paid service on those free options in order to set that up. and even then you won't have the freedom or possibilities that you get with having your own virtual private server. Uh so the way that we're doing it in this video will give you a lot of freedom and room for your application to grow, but it's not as simple as some other methods. So there's definitely some trade-offs there. Okay, so first things first, for those of you who have been following along with this Django series, I need to make one correction to the actual Django code before we deploy this. It worked in development, but when I tried to deploy the application, it gave me some issues. Uh, so the correction that needs to be made is in our users models. py file. So I'm going to open that up really quick and make a quick change. So I have my application open here in Sublime Text. And this was in let me uh maximize this here. This was in our users app here. And this was in uh models. py. And the mistake that I made was down here in our save method. Uh so when we're calling the save method on our parent class, this super.save save we need to accept any other arguments that our parent class might be expecting. So in this case uh we need to pass in uh args which are positional arguments and quarks keyword arguments into that save method. Uh so to do this I will just accept uh positional and keyword arguments here by doing star quarks and or star args and star quarks. And we also want to pass those in to our save method whenever we call that on our parent class. So again, what that does is if you've watched my video on functions before, then you'll know that the convention of passing args and quarks to your function allows you to accept any arbitrary number of positional or keyword arguments. Um, okay. So with that correction in place, let's now deploy our application. So like I said, I'm going to be using Lenode to deploy this application to a Linux server. That's my personal preference, but you can do this uh same deployment with any Linux server that can that you can access via SSH. Now, I already have an account with Lenode. So, let me go ahead and pull that up here in my browser. So, I have a tab open here and I'll refresh this page. So, if you create an account with them, then you should be able to access a page like this as well. This is their new cloud manager and that's at cloud.lenode.com. Uh now, there's also a Lenode manager at manage.lenode.com. lenode.com, but that's older and I believe they're now steering people towards using this instead. So, this page gives me access to all of my current Lenode servers. So, you can see I already have one created for my personal website here called CoreyMS-Server, but we're going to create a new one from scratch to deploy our Django application. So, let's go ahead and see what this process is like. So, first I'm going to come up here to create and we're going to click on create and we want to create a new Lenode. Lenode is their name for their you can see here it says high performance SSD Linux servers uh for all your infrastructure needs. So we're going to click on that to create a new Linux server. And now we need to select what image we want to create uh with this server. So I'm going to use Auntu uh server in this video. Uh but depending on what your preference is, you can use any of these. Uh CentOS might be another option or Fedora, but I'm going to choose Auntu. So for the region, I'm going to come down here. I'm just going to pick Dallas, Texas. It's a nice midpoint in the United States. Uh you can see that they also have some regions in Europe and Asia as well. Uh so depending on where people are going to be accessing your application, you might want the server to be served up to them from a close location. So for this application here, I'm just going to choose Dallas, Texas. That's fine. So down here for the Lenode plan, uh this is where you pick how much performance you want in your machine. And you can see the prices are attached here. So this one is $10 a month. This one is $20 a month. Now, this is their standard plan here. They also have something called a nanode here. And if we click on that, you can see that this is a pretty low performance machine. It's just got one CPU, uh, 25 gigs of storage, and a one gig of RAM, but it's only $5 a month. And our application, especially if you're just testing, uh, most likely isn't going to be very, uh, intensive. So, I'm just going to pick their cheapest option for deploying our Django application. Now, you can always resize these later. So, I just suggest going small at first. And if you want to bump it up to something bigger, depending on, you know, how much traffic you're getting, then you can do that at a later time. Uh, okay. So, down here at the label, I'm just going to call this uh Django-Server. Okay. So, for the tags, I'm just going to leave that empty there. So, now we need to choose a root password. So, this is going to be the root password on the server. So, you're going to want to pick something secure. Um, for me, I'm just going to uh put in a password of this is a test. Now, I'm going to delete this server after this video. So, you know, you're not going to be able to log into my uh server as a root or anything like that. Now, whatever password you choose here, be sure that you remember this because this is the root password on your server and you're definitely going to need to know it whenever you first log in to your computer. Uh, so, you know, definitely remember this uh for later uh because we are going to be using that. So now that we have that, I'm just going to go over here and click create. And now it's going to create our server for us. So you can see here that our Django server, it says that it is provisioning the server. And now it is booting up. Uh so I'm going to go ahead and fast forward to where this machine is fully created. Uh but it shouldn't take too long, just a couple of minutes. Okay. So once our server has completed booting up, uh we can see our server here within our list of Lenodes. Uh we can also go to our dashboard and see it here. Um now if we click on our Lenode then it'll give us more options with this. So click on that Django server that you just created whatever you named it. And now go to the networking tab. So we can see that we have a lot of tabs here. Summary volumes networking uh settings everything like that. Let's click on networking. And down here we see access. And the first thing it says here is SSH access. So, let's copy this because we're going to SSH into this machine. So, you're going to want to copy that SSH command and paste it into your command line to SSH into your newly created server. Now, if you're on Windows, then you won't have access to the SSH command in the command line. There are other tools that you can use that allow you to SSH into a server. So, one of the more popular ones is called Putty, and I have it here on uh I have their website pulled up here. It's at uh putty.org, or and they have documentation in here of how you can SSH into a server. Uh but personally, what I would recommend on Windows, if you're on a newer version of Windows, is to simply install the Linux bash shell on Windows and you're able to use SSH through that. That's what I personally do on my Windows laptop anytime I need to connect to a server. Now, I'm not going to show that process of installing the Linux bash shell on Windows in this video because I already have a separate video detailing that whole process. So, I'll put a link to that in the description section below if anyone wants to watch that. So, [snorts] once you're running Bash, then you should be able to use SSH. And again, if you don't want to use Bash for any reason, then you should install the software called Putty, uh, that allows you to use SSH on Windows here at putty.org. But I will say that if you're using a Linux bash shell, then it'll allow you to more easily follow along with all of the commands in this video. Um, okay. So if you're using bash then we'll want to copy this SSH command here for uh from our networking tab in Lenode and let's paste this into our command line. Now I have two different terminals pulled up here right now. Now one of these I'm going to use to run commands on my local machine and one I'm going to use to run commands on our remote Lenode server. Now you don't have to do it this way but if you only use one terminal window then you'll have to go back and forth between your local machine and your server. So, I think it's easier to simply have two windows open. And let me actually minimize our uh browser here in the background so that we only have our terminal windows open here. Um, okay. So, now I'm going to paste that SSH command into my terminal on the left side here. So, on the left I'm going to have our remote server and on the right I'm going to have our local machine. So, I'm going to paste in that command and hit enter. And this is going to ask you uh if you're sure that you want to continue connecting. This is only going to ask you this the first time. So I'll just say yes. And now it's asking for that root password. This is what we uh created when we created our Lenode. So for mine I had that as this is a test. So if I insert that password then we can see that that worked. We are now sshed into what is going to be our web server. So you can see that we are uh root at localhost. So localhost this is our Lenode server. So we are actually in the terminal of that machine. Um so first let me clear the output there. Uh first let's install some software updates. This is just something that you're going to want to do uh for the first time that you get onto your Linux machine. Now I'm actually going to minimize this right side here and uh expand this over so that we have more room to work with here on our server. Um so to do this now remember I'm on Iuntu. So, I'll say apt get update. And then I will also type in these two ampersands and then aptget upgrade. And let me make sure I spelled that right. And this is just going to go through and update our machine and make sure that we have all the latest security patches and things like that. It might ask you occasionally if you want to continue. So, you might have to hit yes a couple of times through this. And this could also take a little bit of time. Uh so I'm just going to fast forward into where uh this is done. Okay. So after a couple minutes those software updates should complete. Uh so now I'm going to clear my screen here. Um so now what we want to do is we want to set the host name of this new machine. So on Auntu we can do that by saying uh hostname ctl set dash hostname. And now let's put in whatever we want the host name to be. So, I'm just going to say Django-Server here for this machine. And we can check that that worked by typing in hostname. And we should get Django server there. Now, remember, I did use iuntu for the operating system for this example. Uh, but if you are using something like CentOS or Red Hat, then some of these commands are going to be different. So, you're going to have to uh map the differences between those uh if you're using a different operating system than what I'm using here in this tutorial. Okay. So, now we also need to set the host name and the host file. So to do this, I'm just going to use nano because nano is a simple editor that most people know how to use. So I'm going to say nto nano and this is in the etc directory and this file called host. So I'm going to nano on that and underneath this 127.0.0.1 I am going to put in the IP address of our server. Now you're going to need that IP address a lot. So it would probably be a good idea just to write it down. Um, now this is the IP address that we used in our SSH command. Now, I think that I still have uh that command pasted in or copied into my clipboard here. And I do. So, I'm just going to get rid of that first part. And there is the IP address that we want to put in there. So, we want to put in that IP address and then hit tab. And now we want to put in uh what we had as our host name. So, that was uh Django- server. So if I now hit Ctrl X and then yes to save and then just hit enter to keep the same file name and that should finish up setting the host name. Okay, so now we want to add a limited user. So right now we're logged in as the root user. The root user has unlimited privileges and can execute any command. Now, that might sound nice, but it's best practice to add a new user that has limited privileges that you can use as your main account. And you'll still be able to run admin commands using the sudo command. So, let's add this limited user. So, I'm going to say add user. And the user that I'm going to create is going to be Corey MS. Now, you can put whatever username you want here. Um, so I will hit enter there. And now it's asking us to put in a password. So again, I'm just going to say this is a test with a few capitalizations in there. Uh same password again. And now it's going to ask you to fill out a little bit of information like your full name and stuff like that. This is actually optional. You don't have to do this. So I'm going to put in my full name, but for the others here, I'm just going to leave blank and hit enter. And then uh it's going to ask if that information is correct. I'll just accept the default of yes. And that created a new user for us. Now we want that new user to be able to run uh you know root commands. Uh so we want them to be able to use sudo. So way the way we can do that and I'm going to clear the screen here. The way we can do that is to simply say uh add user corey ms and then just put sudo after that and that will uh it says here adding user corems to the group sudo. Okay. So now we have created a new user on this Linux server and now we can just log in as that user. It's not good practice to log in as root because there's a lot of things that you can mess up that way. Um so let's exit out of our server. So I'm going to exit and now let's log back in. But so I just hit up arrow there to log back into our server but instead of logging in as root I'm going to log in as Corey MS as the user that we just created. So, you want to fill in whatever user you created here. So, when we hit enter, it's going to ask for that user's password, and that's what we uh put in whenever we created the user. Oh, and it looks like I mistyped that. Let me try one more time. Okay. So, now we can see that we logged in as our new user. So, I'm going to uh clear our screen here. And we can see that we also have our host name there. So, now it's saying that that is the name of our server. Okay. Okay, so now that we have a user created, uh, now we're going to want to set up SSH keybased authentication so that we can log into our server without a password. Um, okay. So, at this point, I know that you might be thinking to yourself like, uh, why do I have to do all of this stuff? I just want to deploy my Django application. Uh, well, the reason that we're doing all of this is because I want to show you what it's like to deploy a real world application and to put the proper precautions in place on your server from scratch. So that includes best practices like setting up SSH keys and firewalls and things like that. Uh you're going to want to do that on any real world application that you deploy. So I may as well include it in this tutorial instead of just showing you the bare minimum. So right now the next best practice that we're going to put in place is using SSH keybased authentication to login in instead of passwords. So by default we're using a password to log in to our web server. we instead want to use keybased authentication and that's more secure and more convenient because it uses keys that can't be brute forced and also allows us to log in without putting in a password every single time and that's great for you know running remote scripts that connect to your web server or anything like that. Now, I have a separate video on SSH keybased authentication as well. So, I'm not going to go into a lot of detail of these commands, but we're going to run through all of them here anyway. But if you want to know more details as to what these commands are doing, then you can watch that video and I'll put a link to that in the description section below. Now, there's actually an easier way to do this by using a command called SSH copy ID, but it's not available on all operating systems. So, instead, we're just going to do this the slightly longer way. Um, okay. So, we are logged in to our web server as our user that we just created. And we are in the home folder. If I do a pwd, that will print the working directory. And we are currently in our home folder here. So, in our home folder, we're going to want to make a directory uh called SSH. So, I'm going to say mkdur-p. That means it's going to uh make the entire tree of the directory. And we want to create that in our home folder. And that's what that tilda is. So home folder and that is going to be ssh. So let's make that. And if you do an ls-la then we can see that we do now have that ssh folder. So now I'm going to clear my screen there. And now we want to go back to our local machine. Uh so if you don't have two windows pulled up then you can uh simply exit out to get back to your local machine. But I am just going to uh use uh this other window terminal here. So here I'm on my local computer. Now again I'm doing this in bash in this tutorial. But if you're using a program like putty on Windows that we talked about before, then you'll have to do this differently to create and copy your SSH keys to your web server. So I found documentation in Lenode's guides for putty users on how you can do this through putty. And I'll put a link to that in the description section below as well. Uh so that you can see how to do that using that software. Um but here in bash we can simply say ssh- key genen and I'm going to do a -b and then 4096. That just makes it a little more secure. Now remember we're on our local machine here. And now it says generating public private RSA key pair. Uh enter the file in which you wish to save that key. And this is in my home folder on my local machine in an SH SSH directory uh with an ID RSA file. I'm just going to leave that as the default there. And it's saying that I have one that already exists. So I'm just going to overwrite that with yes and enter a passphrase. So you can also have a passphrase for this key as well. I'm going to leave that empty, but you can add one if you'd like to make it even more secure. Okay, so what that did for us is it created two keys. So, we can see that it says your identification has been saved uh as ID RSA and then your public key has been saved as ID RSA.pub. Now, what we're going to want to do is put our public key on the server uh so that then we can log in uh without a password. It's going to be able to recognize us because these two keys are going to match. So, let me go ahead and clear the screen here. So, now we need to get that public key to our server. Uh now if you're on Windows and you're not using bash then you can use uh you know FTP or FileZilla or something like that where you can drag and drop. Uh since we're using bash we can just simply use an SCP command. So I'm going to say SCP and that was created in my home folder in this SSH directory. And that was called R ID_rSA.pub. and we want to copy that file up to our server. So now I'm going to say corems, but at this point you're going to want to put in the user that you created, but I'm using corems. And also now we want to uh put that IP address. So like I said, you're going to be using that IP address to your server a lot. So it's probably best to write it down. So I wrote mine down here. Mine is 1 19858.119.183. So after we specify where we want to copy that uh public key to uh the server, now we want to put an exact location in that server. So I'm going to put a colon here. And now we can specify the location on this server that we want to save that public key. So that is within the home directory of this user here. So a tilda there for the home directory and then [snorts] SSH directory. And let's uh save this as a file called authorized_keys. Now, you don't need file extensions on Linux, so we can just call that authorized keys and leave it at that. So, I'm going to run that. And it's going to ask us for our password because we don't have this set up to uh use without a password yet. Okay. And we can see that that was copied over. So, now I'm going to go back to our server here. So now if I do an ls uh on our ssh directory then we can see that now we have that authorized key file. Okay. So now just to finish this ssh stuff up uh we now need to update some permissions. And again I can't go into deep detail as to what every command is doing in this video or else it would just run on for a long long time. Uh but basically what we're going to be doing here is setting the permissions for the SSH directory to where the owner of the directory has read, write, and execute permissions uh on that directory. And the owner of the files in the directory will have read and write permissions on those files. So to do that, we can say uh sudo chmod and that's how we change permissions in Linux. And we're going to do 700 permissions and we're going to do 700 permissions on that SSH directory. So, I will run that. And now it's going to ask for a sudo password. So, we can put in that password. It looks like I may have mistyped. And now I'm going to run that same command, but I'm going to do 600 permissions. And I'm going to do a 600 permissions on all of the files within that directory. So, I'll run that. And if you use sudo uh a good bit, then you don't have to put in the password every time. It'll remember it for some time. Now again, I'm not going to go into a lot of detail here as to what these permissions mean. Uh but basically on Linux, uh the way that the permissions work is this first number here is the permissions for the owner uh of either the directory or the file. The second number here is the permissions for the group. And the third one here is the permissions for everyone else. So what we were saying here with seven is read, write, and execute. And uh with six here, it's just read and write. And those are just zero permissions for everybody else. Um, okay. So now we should be able to log in without a password. So again, I'm going to exit my machine just to test this. So now we're back on our local machine. So I'm going to hit the up arrow to where we logged in, sshed in as our user, and I'm going to hit enter. And you can see that it just logged us in without a password there. So our SSH keys are now working. And that is also more secure than using a password as well. Okay, so we're just about finished up with the SSH stuff, but there's a couple of more things that are best practices to uh change here before we finish this out. Um, so first of all, we want to uh not allow uh root login. We just want to be able to log in as our users. And we also don't want to allow password authentication because we just want uh to be able to log in with keybased authentication. And if somebody needs a password then it means that they don't have the keys that they need. Uh so let's just disallow that altogether. And we can do that within the SSH config file. So that is in the location and you have to use pseudo here. So we'll do sudo nano and this was within uh this etc directory ssh and that file is ssh_config. So we need to put in our sudo password again. So we're going to change two things in this configuration file. So first we are going to change uh the permit route login. So if you scroll down a little bit then you can see that this is the first one uncommented here. And right now it's set to yes. We're going to set that equal to no. And let's scroll down a little further here. And there should be a commented one that says uh password authentication. So we can see here this one is commented out password authentication. So let's uncomment that. And it's already set to yes. Let's instead set that to no. Um okay. So now let's save that. So in nano you hit controlx and then a Y to save and then enter just to keep the same file name. And now we need to restart the SSH service. So we can do that with uh sudo systemctl restart sshd. So let's run that. And that should have restarted our SSH service. Okay. Okay, so we're almost ready to push our Django application. There's just one more thing that we're going to do and that is setting up a firewall. But this is going to be very quick. Um, so first we need to install something. So I'm going to clear my screen. So let's say sudo aptgetit and we're going to install something called UFW. And ufw stands for uncomplicated firewall. This is a lot easier than using like IP tables or something like that. Okay, so now we're just going to set up a few basic rules. So, first we're going to say sudo UFW uh default and we are going to allow outgoing and hit enter there. And now I'm going to hit the up arrow and I'm going to put in another rule and this is going to be uh deny incoming. Let me spell that correctly. Deny incoming. Now, configuring a default deny rule that denies all incoming traffic uh can lock you out of your server unless you explicitly allow SSH. So, be sure that you've configured these next allow rules uh for SSH and HTTP before applying our changes. So, to allow SSH, you need to say sudo ufw allow. And we can just allow SSH. Okay, so that's good. Um, now I'm not going to allow HTTP right now. instead. Uh, since we're going to test our site before we actually make it live, I'm just going to allow a certain port. Now, if you remember, our Django development server runs on port 8000. So, let's just allow that port for now. And that's how we'll test it on this Lenode server. And if it's all working, then we'll allow HTTP over port 80. So, I'm going to allow 8,000 there. And we can see that these rules were updated. And now we need to enable these. Uh, we're getting a little far down here. So, let me clear my screen. Okay. So, now we need to enable these. So, I'll say sudo uh UFW uh I'm sorry, enable, not allow. So, sudo UFW enable. I'll run that. And it says command may disrupt existing SSH connections. So, hopefully you remembered to allow those SSH connections. So, I'm going to say yes. And [snorts] now if we do a sudo UFW status, then we can see everything that is being allowed here. So port 22 is SSH and port 8000 here is what we're going to use to test our Django application before we make it live on port 80. So I'm going to clear the screen. Okay, so that's going to finish up all of the new Linux server setup type of stuff. So now we're ready to actually deploy our Django application. So first we want to put our application on the web server. Now there are multiple ways that you can get this application to your web server. Uh so if you have it checked into a git repository then you can simply use git to do a git clone to our server here. Uh you can use an FTP client like FileZilla to push it to the server. Uh since we're already in the command line on our local machine, we can just use the terminal command to do this. So, I'm going to pull up my other terminal window here where I'm on my local machine and let's clear the screen. Now, before you push your Django application, if you're using a virtual environment for your application, then you're going to want to create a requirements.txt file that captures everything that we need to install for our Django application to work. Now, I was using a virtual environment for this series. So, I'm going to activate that and then create a requirements.txt file from that environment. [snorts] So uh I am going to activate my virtual environment. So I'm going to say source and that environment lives on my desktop and this is called Django env. And that I have to run I have to source the activate file. So bin-activate. So now we can see in our prompt here that that Django environment is now activated. Now if we want to see all of the dependencies that we have for our application then we can simply run pip freeze and if we run this then we can see it uh displays everything that we're using in this project. So we have Django Django crispy forms pillow uh and some of these are dependencies on others. So, PITZ uh is a dependency that Django uses and you can see that this also provides all of the uh versions the exact versions that we were using in development as well. So, uh saving all of these and then installing those on our server uh should make sure that uh you know no updates or anything are going to break our application because we're installing exactly what we were running in development. Now, if you're on Windows then you can create a requirements.txt txt file and then just paste all of this uh here into it. Uh but if you're on Mac or Linux or using bash then we can simply say let me clear my screen here. We can simply say pip freeze and then we can feed that into a requirements.txt file and that'll that will create a requirements.txt file with the contents with the output of that pip freeze command. So I will run that. And now we want to put this requirements.txt file into our Django application. Uh so I am going to open up finder here. Um and I have two windows opened up. So this is my desktop here. Now let me open up my Django project. So this is my Django project and this is my desktop. I'm going to Well, I thought I created the requirements.txt file uh on my desktop. Uh but actually I'm within my home folder instead. Uh, sorry about that. So, let me go to my home folder. So, here is that requirements.txt file and I'm just going to drag this over and drop that into my Django project. So, now that requirements.txt file is inside of our Django projects and I'm going to close down uh those Finder windows. Okay. So, now we need to put our application onto our web server. Now, since I'm using Bash, I'm going to use the same SCP command that we used earlier to copy our uh SSH keys. But if you're not using bash then again you can use something like FileZilla or Git to get your project uh folder onto the server. Okay. So to do this uh first I'm going to navigate to my desktop because that is where my Django project currently lives and that project is called Django project. So now I'm going to say SCP uh which will copy and we need a r here to do a recursive copy. That means that we can copy a directory. Um, so now I will do uh Django project. That's what we want to uh copy to our server. And we want to copy this to uh corems at now you want to use whatever user you created there. And now the IP address. So again I wrote this down. You want to use your IP address. Mine is 1 19858.119.183. And again to specify an exact location on that server, we can put a colon. And I'm just going to put this in the home folder on uh for this Corey MS user. So after the colon, I'm just going to put a tilda and a forward slash. And that should put it in the home folder on that server. So I'm going to run that. Okay. And that copied everything from our Django project onto our server. So now let me minimize our local machine here. and go back to our server that we still have open in this terminal window. And now let me do an ls on the home directory to make sure that that copied over. And we can see that it did. We have our Django project here. And if we do an ls on Django project, then we can see that it has all of our applications. So it's got the main Django project here, the users, the blog, and our uh SQLite file, everything. Okay. So now that we have our Django application on our web server, now we're ready to actually get it running on here. Uh so first of all let's create a virtual environment that is going to run our application. Uh so to do this we're going to need to install a couple of things. So I'm going to say sudo aptget install and we want to install. So first I'll install python3-pip. Now you want to do the python 3-pip because if you don't put the three there it'll do python version two. So, we'll do a pseudo install of Python 3-PIP. Now, some of those installations can take a bit. Uh, so instead of watching the entire installation throughout these videos, I'm just fast forwarding to where these are complete. Uh, so if you're following along and yours is still installing, then you can just pause the video until yours is done as well. Um, okay. So, I'm going to clear my screen here. And now let's install uh Python 3's virtual environment. Uh so I'll say sudo apt-get install and this is going to be python 3-ven and I will say yes there. Okay so once that is finished installing now I'm going to create a new virtual environment. Uh now you can create this virtual environment anywhere that you want but I'm going to put this inside of our Django project folder. So to create a virtual environment, we can simply say python 3-m venv. And I'm going to put this within our Django project folder. And I'm going to call this virtual environment just simply venv. So now if I do an ls on our Django project, then we can see that we have a virtual environment right here. So now let's activate that virtual environment so that we can install all of our dependencies. So, I'm going to cd into our Django project directory. And within here, I'm going to say source venv bin activate. And that should activate our ver virtual environment. We can see here at the beginning of our prompt, we now it now says venv. So, that's a good sign that our virtual environment is activated. Okay. So, now I'm going to install all of those dependencies from our requirements.txt file. And remember our requirements.txt file. We just put that here within our Django project. So we can simply say pip install. And if we do a -ash r on pip install, then it'll expect a requirements.txt file. So we can say requirements.txt and run that. And it's going to go through and install everything in that requirements file. So it's going to install Django and Pitz and uh Crispy Forms and all of that. Now, if you didn't create a requirements.txt txt file. Then at that step, you still want to create the virtual environment, but you're just going to install those manually. So, you just install the version of Django that you used in the series and then Pillow and Krispy Forms and all of the other uh packages that we used throughout the series. Okay, so now that we have all of that installed, let me clear my screen here. Um, now let's change some settings in Django so that we can test this on our Lenode server. So, first I'm going to open up our settings. py file. Now, that is located. So, I'm going to do a sudo nano that is located inside of Django project settings. py. So, I will run that. And there are a couple of things that we need to change here. So, I'm going to go down here a little bit and we should see something called allowed host. Now, allowed host, we need to put in our IP address of our server. Now, if you have a domain name, then you can use the domain name as well. But for now, we just have the IP address. Now, this is going to be a string. So, uh I wrote my IP address down. You would insert yours here, but mine was 198.58.119.183. Now, you have to have that in allowed host because for security reasons, uh Django isn't going to allow traffic uh anywhere that it doesn't recognize the host. Um, okay. So now with that in place, now let's scroll down towards the bottom here where we put uh Okay, so here at the bottom, I want to scroll up just a little bit to our static URL. So if you remember earlier in the series, I said that static files were handled differently in development than they are in production. Uh so in production, we have to put in a place where these static files are going to exist, and that's going to be the static root. So, right above the static URL here, I'm going to put static_root. And I'm going to set this equal to uh for me, I'm just going to put os.path uh.join. And I'm going to put this in the base directory. So, base dur. It's actually going to be very similar to our media folder here. So, it's going to be in the base directory of our project. And instead of media, we will do static. So, once we've made those changes to our settings, uh let's save those. So I'll hit controll X and then Y to save and then enter to keep that same file name. So now to get our static files working here on the server, we need to run a command called uh collect static. So I'm going to say python manage. py and that is collect static. So if we run that then we can see that it says 120 static files copied to uh this static directory here within our Django project. So if I do an ls now then we can see that now we have a static folder here within our Django project. Okay. So now let's test this. So let's run our development server but we're going to open it up on our Lenode server here to where we can access it from the outside. So I'm going to say python manage. py run server. Now, don't hit enter yet. Uh, we want to do the address of 0.0.0 and then colon port 8000. Uh, remember that we opened up port 8000 on this server. Uh, sorry, this is going to the uh next line here. Uh, but hopefully you can read that. All right. So, if I hit enter there, then it says that uh our server is running. [snorts] And since we specified this as 0.0.0.0, uh, that should allow us to go to our IP address on port 8000 and see this development server running. So, I'm going to open uh, Chrome back up and see if we can access this. So, my IP address was 1 19858.119.183. And to go to port 8000, we can put in a colon and then 8,000. So if I run that then we can see that our blog is uh now available through our browser. So this should be accessible to anybody. So you could send somebody your IP address and that [snorts] port and they should be able to go to your blog and interact with it. Um so let's test the site. So if I go here to create a new user, let's try to create a new user. So I'll do uh test 4 and an email of test4 test.com a random password and let's sign up and we can see that our user has been created. Let's try to log in with that user. So test for and then the password that we used. So we can see that we can log in. It gives us a default uh profile here where it has all the information that we uh entered. So let's test that we can create a new post. So test post test content. If we post that then it looks like our post was created. Um let's try to update a post. So I will do test updated post and that seems to work. Um let's try to delete a post and that seems to work as well. Um let's try to update our profile picture. You want to be sure that you test a good bit of functionality uh just to make sure that it all seems to be working properly. Uh so let's update a profile picture and that seems to work as well. Um let's test the logout. Okay. And the logout works. And lastly, let's test the admin page. So I'm going to go to foradmin and then put in uh the user I created with admin access is Corey Ms. and I will log in here. Okay. And it looks like our uh admin page works as well. Um so now I'm going to log out of there. Okay. So it seems like most of our functionality is working on our server now. So that is a really good sign. Now one bit of functionality that isn't going to work yet is our forgot password functionality. So, if I go to forgot password and try to reset my password, then it's going to give me an error. And the reason is is because we haven't copied over our environment variables from our local machine that contain our email service username and password. So, that's one bit of functionality that's not going to work right now, but we will get that set up here in just a bit. Um, okay. So, our site is working, but you don't want to actually leave it like this. So, I'm going to go back to our terminal here. Now, we don't actually want to run this using the Django server like we've done here. This was just for testing that everything worked so far. But now, uh, let's kill that server that we were just running. And now we want to run a server that's more reliable. So, you know, something like Apache or Engine X or something like that. Um, now in this video I'm going to use Apache, but there's different options available to you. And let me actually minimize our browser there. Okay. Okay. So, there are a couple of things that we need to install here. First, we need to install Apache, which is going to be our web server. And then we're going to install something called mod whiskey. Now, whiskey, which is WSGI, stands for web service gateway interface. And that's what allows our web server, in this case, Apache. It allows our web server to talk to Python and to talk to our web application which in this case is Django. So we need to install and configure both of those. So first I'll install Apache. So I'll say uh actually let me go back to my root directory here by typing cd so that we have some more space here. Um so now I'm going to say sudo aptget install and this is going to be apache 2. So let's run that. Okay. And once that's installed, I'm going to clear my screen here. And now let's install mod whiskey. So to do that, that is uh sudoapp get install. And this is lib Apache 2-mod whiskey-p3. I always have to look that up. I can never remember these long package names. So I think that should work. Let me run that and hit yes. Okay. So it looks like that was installed successfully. Um, so now we need to configure our Apache web server. So I'm going to clear my screen. So now let's cd into a uh directory here in etc uh Apache 2 sites available. And this directory here is where the Apache configuration files live. So if I do an ls in this directory here, then we can see that there are some default configuration files here. Now I'm going to use one of these configuration files as the starting point for our project's configuration. [snorts] So I'm just going to copy one of these. So I'll say sudo cp and I will copy that first one. So 0000 default and I will copy that into a file called uh django project.com. And again, sorry for the uh text scrolling onto multiple lines here. I know that that can make it a little bit more difficult to read. Uh but I have to make a trade-off between having the text large enough to where you can read it, but you know, sometimes that uh makes it harder to read when it goes onto multiple lines like that. Okay, so now we've created this Django project.com configuration file that is a copy of the default configuration file. So [snorts] now let's edit it to uh where it uh meets the needs for our project. So I'm going to do pseudo nano uh and change that django project.com file. Okay, so what we have here is a default configuration file uh for Apache. Um now where it says virtual host uh 80 right here this 80 it means port 80. So this is what's going to show up on HTTP port. Um so whenever we go to our uh IP address in the browser uh it's going to follow these rules. So I'm going to scroll down here towards the bottom. All of this stuff is just default standard stuff. So right here before the closing virtual host tag I'm going to add in a few of our own rules. So, first of all, we're going to use an alias to tell Apache to map requests starting with static to our apps static folder. And remember in our project settings, we put this in our project's base directory. So, to do this, I'm going to say alias, and we want to alias anything that references static. And we want that to go to our project's static directory. Now, on my machine, uh, this is located in my home directory, and my user is Corey MS. You're going to want to put your user there. My project is called Django Project. You're going to put want to put your project there. And I put that static folder uh in my Django project directory. So, that is where mine is located. You want to put uh where you put your static directory there. [snorts] Um, so now we want to give some permissions here. So we're going to say for that directory oop sorry that needs to be capitalized. So we'll say directory and the directory is going to be the same thing that we put here. So I will just try to copy that and paste it. And within that directory tag uh we are going to say require all granted. And now we can close out the directory tag. So we will put a for slash there and directory. And now we want to create another one of these for the media folder as well. So I'm just going to copy that big whole section there and paste that in. And up here where we had static, we want to change these to be media. So I will change this one here to be media. And then here at the end, I will change that to be media as well. And one more place right there. Okay. Okay. And now that we have the static and media directories taken care of, uh next we need to grant access to the uh wsgi.py file within our project. This ensures that Apache can access our whiskey.py file. Uh which is how our app is actually going to talk to our web server. So to do this, I'm going to scroll down here just a little bit. So to do this I am going to copy uh up until this point of this line here and paste this in. But for the directory here uh I also want to go one more level deep and I want to go into uh the Django project directory within our Django project. And that's because that's where that whiskey. Fi pi file lives. So now within there and I'm just going to go ahead and close this off right now so I don't forget later. So within here we want to uh create some file tags. So I will say files and that is wsgi.py and I'll also close off that files tag there as well. And within here, we also want to say uh require all granted. Okay, so we're just about finished up here. Just a couple of more uh things to add. So next, we're going to add the part that actually handles the WSGI part. So we're going to use uh the demon mode for this. And this is recommended in Django's official documentation. So to do this, let me scroll down here just a little bit so we can see this a little better. So to do this I'm going to put in a tag here called wsgi script alias and then we are just going to put a forward slash and then we will do a forward slashhome coreyms. You're going to want to put your user in there uh django project_wsgi.py. So the first bit here is the base URL path where we want to serve our application. Uh and in this case it indicates the root URL. Um so basically that means going to the base of our IP address without any extra routes will take us to our Django application. And the second part here is the full path to that wsgi.py file. So once we have that done now we can specify the demon process. So, I'll say wsgi d a m o n is how you spell that. Uh, demon process. And now we can uh just call this whatever we want. It's uh just going to be the process. So, we'll just call it Django app. And now I can say python path and I don't want any spaces there. So, python path equal to this is going to be the path to our project directory. So on my machine that's for/home slashcorems/jeno project. Again you put in the path to your Django project there. Um and now uh we also need to specify python-home and for python home I'm going to say that equals and this is going to be the location to our virtual environment. So I'm in on my machine that is for/home/coryms/jango_project slv. Now I know that this is a lot of typing and it might be easy to uh mess something up here or mistype something. So I'm going to uh take this configuration file once we're done with this video and I'll put this in my GitHub page so that you can compare it to yours uh to see, you know, if you've made any mistakes. Um, okay. So, with that said, uh, we only have one more line here to finish up this configuration. So, this is going to be WSGI process group. And we want this process group to be equal to this process here that we specified in this Damon process. So, I'm just going to uh, type in the same thing there. So, Django app is what we named that process. Okay. So, hopefully we didn't make any typos there and got everything correct. Um, so I will save this file. So within nano it's control X uh a Y for yes to save and then just hit enter to keep the same file name. Um, so now I am going to clear my screen and I'm going to CD back to my uh home directory here so that we have a little bit more typing room. So now let's enable that site through Apache. So to do that we can say sudo and this is a2 en site to enable the site. So that's apache 2 enable site and then we want to uh specify that Django project and I will hit enter there and you can see that it's telling us that to activate the new configuration we need to restart Apache. We'll do that in just a minute. Um now I'm also going to disable the default site. So I'm going to say sudo uh a2 for apache 2 disc for disable and then site and we will disable that uh 0000 default comp. Okay. So now that default site is disabled and our Django project is enabled. Um okay so now let's finish up with doing some file permissions here. So there are still a couple of things that we need to change. So right now we have [snorts] to give Apache access to things like our uh database because we are right now we're using SQLite. In a future video we're going to use Postgress but right now we're still using SQLite. So Apache has to be able to read and write from that SQL light file. And the same goes for our media folder. So if somebody is uploading a picture then Django has to be able to write to that media folder. So, let's do a few different permission updates here. So, I'm going to say pseudo ch own, which changes the owner of a directory or a file. And I'm [snorts] going to do a colon www data. That is the uh Apache user there. And we want to uh change the permission in Django project dbsqlite 3 is the name of our database file. So what this is going to do is it's going to uh make Apache the group on that file. So if I run that then now Apache is the group owner of that file. And now I'm going to change the permissions. So I'll say uh pseudo chmod and the permissions that we want here are 664. So again that's a six for the owner, a six for the group and a four for everybody else. A four is uh read permissions. And I want to um give permissions to Django project DB.SQL light 3. Okay. So I also want that www data group to own the Django project folder itself as well. So I'm going to say pseudo chown and we will put in a colon www data and we will uh change the ownership of the Django project itself. So I will run that. Now if we do an ls-la then we'll be able to see these permissions. So if we see django project here we can see that now corems is the owner but it is now www data is the group owner. So that's what that chown command is doing. Okay. So now I'm going to clear the screen here. Now let's do those same things for the media folder. So, I'm going to say pseudo cho WN. And now we're going to do a -ash r for recursive. Um, and again, we're going to do a colon www data. And we want uh to give permissions here on the media folder. So, I'll say for Django project/media. So, I'll run that. And that will allow Apache to uh actually write uploaded media to that media folder. And now let's change the permissions here. So I'm going to do a pseudo chmod-r and [snorts] we will do a 775 and we will do Django project media again and run that. Okay. So I know that this has been a long video so far but we are just about finished up with uh the final deployment of our Django application. There are just some final changes that we need to make before we go live with our website. So the first thing is that we need to move sensitive information to a config file. Now uh I was using environment variables in the development of this application but in Apache environment variables can be a little tricky to work with and you have to change the WSGI Python file and things like that. Uh since this video has already been long enough and we've done so much configurations, I think it would be a lot easier to just do a config file for this sensitive information uh instead of doing environment variables. So the sensitive information that I'm talking about is going to be like our secret key for our application and our email username and our email password that we use to reset our password in the application. And in the future, this is also where where we are going to add our database username and database password and things like that when we use Postgress. So I'm just going to create a config.json file on our system that holds that secret information. So I'm going to put this in. So I'll do a sudo touch which will create a file and I'm going to put this in the etc directory and I'm just going to call this config.json. Now if you have you know multiple applications on the same server then you can have the name of your application-config.json or something like that uh to differentiate between their different applications. So I'm going to run that to create that file. And now I'm going to grab our secret key from our application. So to get the secret key I'm going to say sudo nano and that is within Django project Django project settings. py. If I run that and scroll down just a little bit here, then it is close to the top of our settings. py file and you can see here it says security warning keep the secret key used in production secret. So if you're using something like git, then you don't want to uh you know have this pushed up to GitHub or something like that. You want to either use an environment variable or load it in from a config file like we're going to do here. So, I'm going to uh copy this secret key. Copy. And I will now erase this here. And we will add this back in in just a second. But for now, I'm going to uh save that settings file. And now, [snorts] let's open up that config.json file that we just created. So, I'm going to say sudo nano, and we put that in -c config.json. Now this is empty right now. [snorts] But to create this JSON file, I'm going to put in opening and closing braces there. And now I will put in a key for the secret key. And I will give that a value. And this is going to be within quotes here. Now we're going to paste in that secret key that we copied from before. [snorts] Now we're also going to put other secret or sensitive information in here as well. Uh so our email user that we use to uh send emails through our email service, we can put that email address in here. And we also need our email password. So I'll say email_p pass is what we called it in our application. And I will put that in here as well. Now you're going to want to put your email username and your email password that we used in this series. Uh now I'm going to use my own. I'm not going to show you uh my email username and password here for obvious reasons. I don't want you to be able to log into my email. Um but so I'm going to exit out of this um file now, but before I actually run this live, I'll fill this in off of the recording uh so that we can see that it works properly. So now I'm going to save this file. So controll x y to save and then enter. And now we want to update our settings. py file uh and pass in the values from that config file. So I'm going to run that same command that we ran earlier, sudo nano, and we want to run nano on our settings. py file. So I will run that. Now here at the top of our settings py file, I'm just going to import JSON. Now I used JSON for my configuration, but if you're more comfortable using YAML or something like that, then you can definitely use that as well. Um so now uh here at the top I'm just going to load in this config file. So I'm going to say with open and we are going to open uh that file. So that was in for/etc config.json [snorts] and we will open that as a config_file and within here I will say config is equal to json.load load and we will load in that config file. Make sure that I spell that correctly. We will load in that config file. And I think that Nano is putting in more spaces here uh than what I'm used to when I hit tab. So instead, I'm just going to use spaces. So I'll put in four spaces there instead. Okay. So with that config file loaded, these should be the last changes that we need to make uh in our settings. py file. So here for our secret key uh remember we loaded in that JSON file and JSON whenever you load something in and use JSON.load it loads that in as a dictionary. So now our config variable should be a dictionary with all of our sensitive information. So for our secret key here, I'll just say uh config and access that secret key of that config dictionary. And that config variable that we are using there. Uh let me show you just one more time. That is what we set right here. That is that variable. That is the JSON that we loaded in. So let me go back down to our secret key. And now that we've set the secret key to that uh sensitive information, now we also need to set debug equal to false. You don't want debug equal to true on your production machine uh because anytime there's an error, it's going to give uh way too much information to people and it could, you know, expose uh other flaws in your system to uh people who could hack into your system or something like that. So you always want debug turned to false in production. And you can see that Django says that here too. They say security warning don't run with debug turned on in production. Okay. And we are almost done. Let me scroll down to the very bottom here where I set my uh email username and email password information. So that's at the very bottom of the settings. py file. And you can see here uh we were using environment variables. Uh that's what we used earlier in the series whenever we added this functionality. But now I'm using that config file instead. So instead of os.environ.get I'm just going to say config.get. And we will keep that as email user. And instead of os.environ.get that is config.get. And now I will save our settings. py file by hittingtrl x y to save and enter. Okay. Okay, so now that we've updated our settings py file, let me clear my screen here. Now, at this point, I'm going to pause the video and I'm going to go back into my configuration.json file and I'm going to put in my uh uh email username and my email password. And then I'm going to uh start the video back up so that whenever we actually test this in production, then we can see that uh the emails actually work when we try to reset our password. So I'm going to go ahead and do that now. Okay. So I went back into my configuration file and I put in my information for my email, username, and password. Uh you'll have to go in and do your information there. Uh but now that should be it. Like we should be ready to go. It should be fully deployed at this point. Um, so now all we need to do is a couple more commands here. So we want to uh disallow the um port 8000 that we were using to test earlier with our firewall. So what I'm going to do is a sudo ufw delete that allow. So delete allow on port 8000. And so we can see that the rule was deleted. And now we want to allow HTTP traffic. So I'm going to say pseudo ufw allow http sltcp. So I'll run that. Okay. And with that done now we can restart our Apache server and it should be good to go. So I will say sudo service Apache Apache 2 restart. So let's restart that and I'll clear my screen. Okay. So at this point, if we did everything correctly, then our site should now be live. So if we pull back up our browser and here before we were at port 8000, if I try to reload that page at port 8000 now, it shouldn't uh give me anything. So we can see up here it's spinning. There's stuff on the screen here, but that's just from before. If we let this wait long enough, it'll say the site can't be reached. Uh, but if we take off that port 8000, hopefully we didn't have any typos in our configurations or settings and it should work. Okay, so we can see that this looks promising. We kind of have our website here. So now let's test the functionality. So [snorts] let's try to first create a user. So I'm going to create a user called deployed user and I'll do an email at deployed user test.com. put in a sample password here and confirm that. So, sign up. Okay, so we got an error here when we tried to create that user. Um, so that means that somewhere along the lines we uh either forgot a step or we made a typo somewhere. Um, now if uh debug was set to true in our settings, then there would be a lot more information here as to what exactly went wrong. Uh, but since debug is set to false, we can see that this is a very vague error. It just says server error 500. Now, like I said before, you never want debug set to true when you're working with a live website because if you have an error like this, you don't want uh just any random person to see all that detailed error information because it can give a lot of information about your back-end server and leave you more uh vulnerable to future attacks. But if we have an error like this, then how do we go about debugging this? Um, well, if you're on a live server and working on a live website, then I would recommend setting up a test server and testing everything there where you can set debug equal to true. Uh, that's not open to the public. Now, since our website here isn't, you know, available for everyone just yet. We don't even have a domain name. I'm just going to go back to our site and set debug equal to true so that we can see what this is doing. But if I was actually working on a real website, then I would probably set up a completely different test server or maybe just open this up on a specific port and then set debug equal to true. But since this isn't uh completely uh live yet, then it's okay to do it this way. So I'm going to say sudo nano and we will open back up our settings here. So settings.py py and I will scroll down here and set debug equal to true. That has to be capitalized there. And I will save that file. And now let's restart our Apache server. So to do that we can say sudo service Apache 2 restart. So now if we go back to our page and try this again. So I'll fill out everything that I just did. So deployed user deployed user at [snorts] test.com and then put in a password. So let's sign up. And now we have more detailed error information. So we can see here that it says uh attempt to write readonly database. Um, so that leads me to believe that it is a permissions error with our database. So if we go back to our server, then let me clear this out. If I do an ls-la, then we can see the permissions here. So I'm going to do that on our project. So our db.SQLite, this is our database file. So uh this is the Apache group here and the group can write to that database. So that doesn't seem to be the problem. If I do an ls-la in my current directory um then we can see that we have the Apache group owns this directory. Uh but it doesn't have write permissions. So the parent directory also has to have write permissions for that database. So that is most likely the problem there. So if instead I say uh sudu chmod 775 on Django project uh remember this is the user here. Uh this is the group. So this will give the group uh read write and execute permissions there with that seven in the second spot. So if I run that and now again let me restart the Apache server. And now let's try testing our website again. So hopefully this will work. Um, and we don't have to make any more changes. So deployed user deployed user at test.com. Fill out password there and sign up. Okay. And it looks like that worked. Okay. So now let's also test all of the other functionality as well. So let's log in with that deployed user that we just created. Okay. So we can log in. So that's good. We can go to our profile and let's try to create a post. So I'll say test post. Test post. Okay. So that works. Let's try to update a post. Test update post. That works. Let's delete one. That works as well. Let's go to our profile and try to upload a new picture. Okay, so that is working for us. Um, let's try to log out. Okay, so that is working. Uh, lastly, let's try the admin page. Uh, let's see. Corey Ms is my admin user. Okay, so my admin page is working as well. Uh, so lastly, I'm going to go back to the site and I'm going to log out. Now, the one thing that wasn't working before was the password reset. But like I said, if uh you went in and you put your email, username, and password into that configuration file that we loaded into our settings, then this should now work. So, I'm going to try this out. I'm going to uh send a reset password to my email address. And we can see here that it looks like it worked. It said an email has been sent with instructions to reset your password. Now I actually have my email opened up in another browser over here. If I reload my email, then we can see that we have an email that says password reset on and right now we just have the IP address. If we had a domain name here, then that would be the domain name. So let's click on that password reset link. And we can see that that looks like it works. So, I'm going to put in a new password here and then try to sign in with that new password. So, that was Corey Ms as the username and then I'll put in the new password. Okay. So, all of that functionality seems to be working. So, now we have a fully deployed, fully functional uh Django application that we deployed to a Linux server. Now if you are deploying your own Django application then I would also recommend uh going to Google and typing in uh Django deployment checklist and the first result should be from their website. They have a deployment checklist on their website here of things that you can go down through and check. Uh so if we just kind of scroll through here um then we can see a couple of things. So like critical settings, secret key. The secret key should be either an environment variable or from a file and we put it in a file. So that's good. Uh you should have uh you should never enable debug in production. We have had that turned off. Actually that's uh good that I thought of that uh because uh we actually need to go back and disable that. Um so I won't do it right now just to wind this video down. Uh, but definitely go back in and set debug equal to false once you're done debugging your application. And you can see that there's just all kinds of different checks that we can make. So here's the allowed host. There's some stuff about caches and databases. So it says database connection parameters should be exactly like your secret key. Either put them in uh environment variables or in a configuration file just like we did. Um, so things like that. This checklist will give you a good bit of things to go through and check and make sure that you did everything properly for deploying your application to production. Okay, so let me go back to the blog here and go back here to the main page. Um, okay. So now we've deployed our Django application to our server and it's accessible through the IP address of our server. Now there's still a lot more that we could do with this in the future if you're interested. Uh so right now we only have an IP address, but if you want then I can also walk through uh the process of buying a domain name and how to get the domain name to go to this server that we've set up. Uh we could also see how to add SSL certificates uh so that we can have an HTTPS domain. Uh that's actually something that I still need to do for my personal website as well. Um now after I record this video, I'm going to uh delete the Lenode server. So, if you go to this uh IP address that I have here, then you probably won't see this website that we just deployed. And that is why it's because I deleted it. Um I'll spin up uh another server with these same parameters uh whenever we're ready to record future videos on this blog. Actually, let me go ahead and delete that server right now. uh that way you can see how to do it if you were following along and using Lenode as well and you want to delete the server also so that you're not charged for it. Um so what we can do is I'll just log in here uh using my account. It logged me out because of how much time we were away. Now here is the server that we created in this tutorial this Django server. Now to delete this, it's just as simple as clicking on your Lenode and [snorts] going to settings and then in settings we can come down here to delete Lenode. And if we click on delete now, it gives you a warning here that deleting a Lenode server will result in permanent data loss. So everything that we did to our server is going to be lost. So I will click delete. And then it'll ask us if we're sure. Click delete. And that server is gone. So, it's no longer charging us money for that Lenode server. Now, like I said at the beginning of this video, Lenode was actually kind enough to sponsor this tutorial. And I've used Lenode for many years and have recommended them to people long before I ever had any sponsors. So, if you get a chance, I would highly recommend giving them a shot. So, like we saw in this video, they have this really nice new uh cloud manager that makes uh spinning up a server fast and easy. Uh you can also choose from available images or you can even upload your own custom image if that's something that you'd like to do. And if you're doing something that is fairly common, then they even have stack scripts that allow you to spin up a server with all of the relevant software ready to go. Um so for example, if you're making a WordPress site or something like that, then you can simply choose their WordPress stack script that spins up a server with WordPress ready to go. So if you were to do something like that, you would come in here and go to create Lenode. We could go to create from stack script. Go to Lenode stack stack scripts and we can see that they have a WordPress server here that would already have all of that ready to go as soon as it spins up. So it's things like that that make this a really nice platform to work on. Um they also have nine data centers around the world so far and they have two more set to open in 2019. So, no matter where you are, you should be able to spin up a server close to your audience. So, if you want to check them out, then feel free to use my referral link in the description section below and you can get $20 of credit applied to your account to try them out. Okay, so with that said, that is going to do it for this video. Hopefully now you have a pretty good idea for how you can deploy a Django application to your own Linux server. Uh, like I said before, this option takes a little more effort than some other options out there, but having your own private server gives you so much more flexibility and room for growth with your application. And doing it this way also provides terrific knowledge for learning more about back-end Linux systems, which is really sought after with a lot of people in the industry. And uh, it's one of those things where if you have it on a job application, it's really going to look good. But if anyone has any questions about what we covered in this video, then feel free to ask in the comment section below, and I'll do my best to answer those. And if you enjoyed these tutorials and would like to support them, then there are several ways you can do that. The easiest way is to simply like the video and give it a thumbs up. And also, it's a huge help to share these videos with anyone who you think would find them useful. And if you have the means, you can contribute through Patreon. And there's a link to that page in the description section below. Be sure to subscribe for future videos. And thank you all for watching.
Original Description
In this Python Django Tutorial, we will be learning how to deploy our application to a Linux Server from scratch using Linode.
If you would like $20 of free credit towards a Linode account, then you can use my link here to sign up:
https://linode.com/coreyschafer
We will be covering the entire deployment of a Django application. This includes spinning up a new Linux Server and tightening its security with SSH keys and firewalls. Then we will install Apache and Mod_WSGI so that we can get our Django App running. Let's get started...
To skip the server setup, jump to 29:11
How to Run Linux/Bash on Windows: https://youtu.be/xzgwDbe7foQ
SSH Key-Based Authentication Tutorial: https://youtu.be/vpk_1gldOAE
SSH Keys on Windows: https://www.linode.com/docs/security/authentication/use-public-key-authentication-with-ssh/#windows
Apache config used in this video: https://github.com/CoreyMSchafer/code_snippets/blob/master/Django_Blog/snippets/django_project.conf
✅ Support My Channel Through Patreon:
https://www.patreon.com/coreyms
✅ Become a Channel Member:
https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g/join
✅ One-Time Contribution Through PayPal:
https://goo.gl/649HFY
✅ Cryptocurrency Donations:
Bitcoin Wallet - 3MPH8oY2EAgbLVy7RBMinwcBntggi7qeG3
Ethereum Wallet - 0x151649418616068fB46C3598083817101d3bCD33
Litecoin Wallet - MPvEBY5fxGkmPQgocfJbxP6EmTo5UUXMot
✅ Corey's Public Amazon Wishlist
http://a.co/inIyro1
✅ Equipment I Use and Books I Recommend:
https://www.amazon.com/shop/coreyschafer
▶️ You Can Find Me On:
My Website - http://coreyms.com/
My Second Channel - https://www.youtube.com/c/coreymschafer
Facebook - https://www.facebook.com/CoreyMSchafer
Twitter - https://twitter.com/CoreyMSchafer
Instagram - https://www.instagram.com/coreymschafer/
#Python #Django
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Corey Schafer · Corey Schafer · 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
Web fonts using CSS Font Face
Corey Schafer
Using Font Awesome in Desktop Applications (OS X)
Corey Schafer
Sublime Text 2: Setup, Package Control, and Settings
Corey Schafer
ArcGIS API for JavaScript Part 1: Our First Web Map
Corey Schafer
Mac Tip: Windows' Snapping Feature on Mac with HyperDock
Corey Schafer
Linux/Mac Terminal Tutorial: Creating Aliases for Commands
Corey Schafer
ArcGIS API for JavaScript Part 2: Starting Templates
Corey Schafer
Paver Patio Time Lapse
Corey Schafer
Mac Tip: Ways to perform Screen Capturing and Screenshots
Corey Schafer
WordPress Plugins: Imsanity
Corey Schafer
WordPress Tips: Test your theme with Theme Unit Test and Monster Widget
Corey Schafer
Sublime Text 3: Setup, Package Control, and Settings
Corey Schafer
Understanding Binary, Hexadecimal, Decimal (Base-10), and more
Corey Schafer
Mac Tip: Adding Folder Stacks to the Dock
Corey Schafer
CSS Tips and Tricks: Add External URLs to Print Stylesheets
Corey Schafer
JavaScript Arrays: Properties, Methods, and Manipulation (Part 7 of 7)
Corey Schafer
JavaScript Arrays: Properties, Methods, and Manipulation (Part 1 of 7)
Corey Schafer
JavaScript Arrays: Properties, Methods, and Manipulation (Part 5 of 7)
Corey Schafer
JavaScript Arrays: Properties, Methods, and Manipulation (Part 4 of 7)
Corey Schafer
JavaScript Arrays: Properties, Methods, and Manipulation (Part 3 of 7)
Corey Schafer
JavaScript Arrays: Properties, Methods, and Manipulation (Part 2 of 7)
Corey Schafer
JavaScript Arrays: Properties, Methods, and Manipulation (Part 6 of 7)
Corey Schafer
Python Tutorial: if __name__ == '__main__'
Corey Schafer
Sublime Text Quick Tip: "Go To Definition" Click Shortcut
Corey Schafer
How to quickly create favicons for the desktop, Apple/Android devices, tablets, and more
Corey Schafer
Easily Resize Multiple Images Using Picasa
Corey Schafer
Easily Resize Multiple Images Using the Mac Terminal
Corey Schafer
Python Tutorial: virtualenv and why you should use virtual environments
Corey Schafer
Python Tutorial: pip - An in-depth look at the package management system
Corey Schafer
Git Tutorial: Using the Stash Command
Corey Schafer
How Software Engineers, Developers, and Designers can volunteer their skills
Corey Schafer
Git Tutorial: Diff and Merge Tools
Corey Schafer
Git Tutorial: Change DiffMerge Font-Size on Mac OSX
Corey Schafer
Sublime Text Quick Tip: Launch Sublime Text from the Terminal
Corey Schafer
Python Tutorial: str() vs repr()
Corey Schafer
Programming Terms: DRY (Don't Repeat Yourself)
Corey Schafer
Programming Terms: String Interpolation
Corey Schafer
Programming Terms: Idempotence
Corey Schafer
Python Tutorial: Namedtuple - When and why should you use namedtuples?
Corey Schafer
Programming Terms: Mutable vs Immutable
Corey Schafer
Python Tutorial: Else Clauses on Loops
Corey Schafer
Overview of Online Learning Resources
Corey Schafer
Mac OS X Terminal Tutorial: Time-Saving Keyboard Shortcuts
Corey Schafer
Git Tutorial for Beginners: Command-Line Fundamentals
Corey Schafer
Quickest and Easiest Way to Run a Local Web-Server
Corey Schafer
Python Tutorial: Generators - How to use them and the benefits you receive
Corey Schafer
Python Tutorial: Comprehensions - How they work and why you should be using them
Corey Schafer
Chrome Quick Tip: Quickly Bookmark Open Tabs for Later Viewing
Corey Schafer
Programming Terms: Combinations and Permutations
Corey Schafer
Git Tutorial: Difference between "add -A", "add -u", "add .", and "add *"
Corey Schafer
Preparing for a Python Interview: 10 Things You Should Know
Corey Schafer
SQL Tutorial for Beginners 1: Installing PostgreSQL and Creating Your First Database
Corey Schafer
SQL Tutorial for Beginners 2: Creating Your First Table
Corey Schafer
SQL Tutorial for Beginners 3: INSERT - Adding Records to Your Database
Corey Schafer
Linux/Mac Terminal Tutorial: Navigating your Filesystem
Corey Schafer
Python: Ex Machina Easter Egg - Hidden Message within the Code
Corey Schafer
Mac Tip: New Split Screen Feature in El Capitan
Corey Schafer
Setting up a Python Development Environment in Eclipse
Corey Schafer
Git Tutorial: Fixing Common Mistakes and Undoing Bad Commits
Corey Schafer
SQL Tutorial for Beginners 4: SELECT - Retrieving Records from Your Database
Corey Schafer
More on: Tool Use & Function Calling
View skill →Related AI Lessons
⚡
⚡
⚡
⚡
Common Next.js Errors (and How I Solved Them)
Dev.to · gary killen
Applying Scalability in Backend (CodeBuddy)
Medium · LLM
Why Every Backend Developer Should Learn Nginx Before Going to Production
Medium · DevOps
Connecting Frontend to Backend: A Backend Engineer’s Reality Check
Medium · Programming
🎓
Tutor Explanation
DeepCamp AI