###### tags: `Tutorials` `Tips and Tricks` `WebFundamentals2021`
# Deployment for Django Based Sites
So you've built a Django based website and you can run it locally, you have it saved on a git service, now what?
:::success
SHOW IT OFF!!!
:::
The quickest way to get your Django app up and running for the whole world to see is through AWS. The way I will go through is free for 1 year, but there are other instances on AWS that you can also use that are either always free or have a resonable price.
## Set up
Easily the most important step to deploying any application but often the first to forget. Before we do anything else we want to make sure that our application is ready for our server instance that we will be creating and deploying our app on.
### A few adjustments and final push to github
1. Folder structure
a. As you all know when we create a Django app sometimes things get messy. So when you look at your repo you should see your project and app folders, any README.md docs you may have, manage.py and .gitignore file. And it should all be in the main branch as well
b. Make sure that you do not have 1 folder that contains all these items, it can mess things up, so something like the below repository.

2. Now make sure your local env is active and be in the root folder so that you can see that manage.py file and do the following
a. `pip freeze`
b. create a requirements.txt file and copy paste what was returned by the above command
3. If you don't have the .gitignore create on now and enter the following 4 items each on their own line.
a. `
__pycache__/
.vscode/
venv/
db.sqlite3
`
4. Once that is done make sure you save all changes and push up through your git
Now We are ready to start the AWS side of deployment
:::warning
Please follow these steps in order and take note of the notes contained for errors and small fixes if things come up.
:::
## AWS EC2:
In this part we will get our AWS instance set up and ready to go.
1. Log into [Amazon AWS](https://aws.amazon.com/)
a. If you have not created an account do so now.
b. You will be asked to provide a CC# however what we will be adding is a free for 1 year instance
:::info
Please note that if you are just now creating an account you may get a message on the next few screens asking you to wait for verification, just give it about 5-10 min and you will be good
:::
2. Once logged in, in the upper left corner you will see services click that and when the rather large menu opens locate and click EC2
a. If you have logged in before you may already see that as a recently visited service
3. You should now see a screen that somewhere a blue button says Launch Instance, click that.
a. They are in the process of updating the dashboard so that is why it is a bit vague
4. How you should see several tabs under the main header and a title of chosing the machine, for our Django projects we will be using ubuntu, so you may need to scroll down to find it, and then click the select button.
a. Currently there are 2 showing 20.04 and 18.04, either version is fine however I would recommend the newest one (20.04)
5. Make sure that t2.micro is selected and then click the Configure Security Group tab at the top
6. You should now see a screen where there is 1 type by default listed, SSH.
a. In that SSH row click the dropdown under Source and change to myIP
b. Add rule - type HTTP source Anywhere
c. Add rult - type HTTPS source Anywhere
7. Once you have those 3 rules in place click review and launch, you should see a popup asking you to select a key pair or create one. We will be creating one
:::warning
Please be sure to follow the following steps carefully
:::
### Creating and saving the PEM file
In the popup box after you have selected create new key pair
1. Give it a name. You can reuse these for other projects so it might be a good idea to give it a generic name (for me it was DjangoInstructor)
2. Now you will download this file.
a. :warning: Make sure to save this file into a folder that is NOT a repository.
b. I saved mine to my base codingdojo folder so it is a file in a folder of projects
3. Once this is complete you will be able to launch the instance
4. Now you will want to view the instance, you should see a table with your instance listed....but the name box will be empty, it is highly recommended that you give this instance a name, I gave it the project name
## Logging into your new Server
:::danger
If you are a Windows user you MUST use a bash terminal or you can download and install PuTTY (The instructions for working with PuTTY will be at the bottom)
:::
1. On the AWS console you will need to click the Connect button (if it is not lit up make sure the instance you wish to connect to is selected)
2. You should get a popup with the commands we will use
3. In your terminal navigate to the folder that contains you PEM file (the key pair we downloaded)
a. I would recommend doing a ls just to make sure you are in the correct folder
4. In the popup windown copy the code that is part of #3 should look something like this
a. `chmod 400 DjangoInstructorMelissa.pem`
5. As long as after you enter that code and hit enter there are no errors you will copy the example code. It should look something like this
a. `ssh -i "DjangoInstructorMelissa.pem" ubuntu@ec2-3-80-69-29.compute-1.amazonaws.com`
6. After you hit enter it might take a min but you should see something like the following:
a. `ubuntu@54.162.31.253:~$`
b. As long as you do you are now connected to your AWS Server.
## Configure the server
The best part about this step is it is the same regardless of the device you are on...as you are now connected to a Ubuntu server and the terminal commands will be ubuntu specific (you'll get the hang of it if you do this enough, all else fails you will have these notes)
:::info
You may get a few prompts while entering the following commands as long as you are using the commands below you can type y or yes for all.
:::
In the terminal type the following commands:
1. sudo apt-get update
a. sudo is a ubuntu command, but basically you are making sure that everything is up to date
2. sudo apt-get install nginx
a. We are installing a package called nginx
3. git clone enterRepoAddressHere
a. Make sure this time you do not use sudo, but replace enterRepoAddressHere with your git clone address..
4. sudo apt-get install python3-venv
a. Now we are installing venv so we can create a virtual environment
5. go ahead and do a ls here you should see 1 folder, your project, cd into it, you should see your manage.py file.
6. Lets create a virtual environment here just inside out project folder
a. python3 -m venv venv - we are using the command venv and naming out environment this as well.
:::warning
Windows users pay attention to this step
:::
7. Activate the environment
a. `source venv/bin/activate`
8. Install the following packages using pip install - django, bcrypt, gunicorn
## Edit settings.py (and other files as needed)
We will use the built in terminal based editor called vim to edit any files that might need some adjusting so remember this section if more edits are needed
1. cd to the folder contianing your settings.py
2. Edit settings.py using vim:
a. sudo vim settings.py
You should now see the contents of your settings file in the terminal, before we get to the actual edit part you will need some information from AWS. We will need the IPv4 Public IP address should be 4 numbers seperated by . 3.80.69.29 in this example below

Now back to our terminal
3. type i to enter insert mode (very very important) You should now see in the lower left corner of the terminal the word insert and change/add the following
a. if it is not already there add import os where the other imports are at the top
b. change DEBUG to False
c. ALLOWED_HOSTS should now look like this
1. ALLOWED_HOSTS = ['3.80.69.29'] - replace my ip with yours
d. Add the following to the end of the doc
1. `STATIC_ROOT = os.path.join(BASE_DIR, "static/")`
:::info
At this point if you have myApp/static anyplace remove the myApp part. Check settings and CSS files as those are the ost common places to have that direct reference. Your general linking of the files in html docs are fine
:::
4. Once those edits are complete you will save and quit using the following keys
a. esc button
b. :wq (all 3 characters)
c. enter key
5. You should now see that you are back in the terminal
6. cd back to the manage.py level folder and run the following command
a. python3 manage.py collectstatic
7. Now is a good time to makemigrations and migrate just like you do locally
8. If you are using the Django admin pannel at all now is a good time to go ahead and createsuperuser as well.
## Setup and restart Gunicorn
Now lets set up and restart our process manager gunicorn.
:::danger
I will use the repoName, projectName, and appName in the following examples please replace these with your actual repository name, project name and app name
:::
1. You should be at the manage.py level folder (so just inside your repo folder) and your environment should still be active
2. Type the following in the terminal
a. gunicorn projectName.wsgi
3. If all is working you should see something like the following
```
[2016-12-27 05:45:56 +0000] [8695] [INFO] Starting gunicorn 19.6.0
[2016-12-27 05:45:56 +0000] [8695] [INFO] Listening at: http://0.0.0.0:8000 (8695)
[2016-12-27 05:45:56 +0000] [8695] [INFO] Using worker: sync
[2016-12-27 05:45:56 +0000] [8700] [INFO] Booting worker with pid: 8700
```
4. click ctrl + c to exit if you see this. (if not please double check all previous)
5. You can now deactivate your environment
6. In the terminal type the following (copy paste if you need to)
a. `sudo vim /etc/systemd/system/gunicorn.service`
7. As we have used the vim command again you should now be in the terminal text editor. type i to enter edit mode and copy/paste/edit the following lines rememeber to change repoName and projectName to yours
```
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/repoName
ExecStart=/home/ubuntu/repoName/venv/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/repoName/projectName.sock projectName.wsgi:application
[Install]
WantedBy=multi-user.target
```
8. Once those edits are complete you will save and quit using the following keys
a. esc button
b. :wq (all 3 characters)
c. enter key
:::warning
Remember the following commands as you may need to use them if you need to make any edits to files after deployment
:::
9. Enter the following 3 commands/lines into the terminal (system ends with an l not a 1 copy paste might be smart)
```
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
sudo systemctl status gunicorn
```
10. Once you hit enter you should see a screen like the following with a green dot
a. 
11. Double check all the steps above if you do not get this
12. ctrl + c to exit
## nginx
Now we are at the last section to get your app up and running.
1. cd to root folder so you should now be at the base level of the server and if you ls you should only see your repo folder
2. Enter the following into the terminal (copy/paste/edit last part to your proejctname)
a. sudo vim /etc/nginx/sites-available/projectName
3. As are again using vim type i to go into insert mode and add the following (remember to change to your information)
```
server {
listen 80;
server_name 3.80.69.29;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/ubuntu/repoName;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/repoName/projectName.sock;
}
}
```
:::info
As a side note this is where you do some changes if you were to deploy to a domain (more about that later)
:::
4. Once those edits are complete you will save and quit using the following keys
a. esc button
b. :wq (all 3 characters)
c. enter key
:::warning
Remember these commands as well if you need to do a restart after the gunicorn commands you will want to run these as well
:::
Don't forget to edit these to your project
5. sudo ln -s /etc/nginx/sites-available/projectName /etc/nginx/sites-enabled
6. sudo nginx -t
This is to test the server as long as you see test successful you are good to proceed, if you get a failure to link but still see test successful you are still good to go
7. sudo rm /etc/nginx/sites-enabled/default
If you already removed this file you will just get a notice that it isn't on the server
8. sudo service nginx restart
If all went as planned you can now browes to your ip address (http:3.80.69.29 for example) and view your site. It may not come up right away but give it 5 min and try again or do a hard reload. Sometimes check https vs http.