Sal
akash "Akash Blog". min read

Deploy Django Application into AWS Lightsail or EC2 instance with nginx and SSL

All the version used in this tutorial

  • Python 3.8.X
  • Django 3.2.2
  • gunicorn 20.1.0

Lightsail Setup

  • Create os only Ubuntu instance
  • After login into our instance, run the following commands to update our instance -> 
    sudo apt update 
    sudo apt upgrade -y
  • In order to use pip3 and venv we have to install some packages -> sudo apt install python3-pip python3-venv
  • Let's create one virutal env -> python3 -m venv env. And activate it -> source env/bin/activate.
  • Now we have to install gunicorn details (make sure you're in the virtual environment) -pip3 install gunicorn
  • Now let us pull the repository and install all the dependencies. After this do the necessary migrations.
  • Let us install nginx details -> sudo apt install nginx -y. now you can check with sudo nginx

Now let us do a little test, we're going to start our application by gunicorn (what is it? will discuss it in later.) -gunicorn --bind 0.0.0.0:8000 project.wsgi:application, after running this we'll see something like 👇🏻

and now we can access our application from our instance IP address, like this xx.xx.xx.xx:8000

  • But now if we close our terminal then we won't be able to access our application.
  • Now we have to do some setup so that our application can run in the background. Here, we'll use systemd

    Create django.service file (you can choose any file name). The file path and content should look like the below.
    sudo nano /etc/systemd/system/django.service

    Content:

[Unit] Description=Topsoil Dev Service After=network.target [Service] User=ubuntu Restart=on-failure WorkingDirectory=/home/ubuntu/project_dir ExecStart=/home/ubuntu/env/bin/gunicorn --bind 0.0.0.0:8000 --timeout 0 --workers=1 --threads=3 --worker-class=gthread main_proj_dir.wsgi:application Environment=You can set here the environment variable [Install] WantedBy=multi-user.target
  • Now we have to run some commands
    sudo systemctl restart django.service
    sudo systemctl enable django.service
  • Now let's do the nginxdetails configuration

  1. Here we need to create one config file in the /etc/nginx/conf/ directory  - sudo nano django_site.conf (you can choose any file name). Paste the below code inside your newly created file
server { listen 80; server_name 54.193.19.108; client_max_body_size 10M; location / { proxy_pass http://localhost:8000; proxy_http_version 1.1; #fastcgi_read_timeout 300; #proxy_read_timeout 300; } }
  1. now let's test - sudo nginx -t - Output -> nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

Our nginx details is up and running 😁. You can directly access your app from Public IP Address (Lightsail)

SSL Setup

* Requirements: domain address which is mapped to your Instance Public IP.

  • Setup SSL certificate with certbot is quite easy. We just need to install some packages and a little bit of setup
  1. Install packages - sudo apt install certbot python3-certbot-nginx
  • Before we generate the certificate, we have to add our domain name in our django_site.conf
  1. Change existing server_name to - server_name testabcdomain.com; (if you want to map multiple domains then use as space separate like this - server_name testabcdomain.com testing.domain.com;)
  • After setup is done, run the below  command
  1. sudo certbot certonly --nginx
  • Now we have to restart our nginx - sudo service nginx restart
  • Now you can visit your secure website 😊.

Django Static File issue Fix after deployment (production)

You might notice that in production, CSS/JS/Images/Fonts files are not working for /admin.This is because of the Static folder issue. In the local development environment Django use Python HTTPServer, and it automatically handles Static files. But in production our server is running through nginx, that's why we have to do little setup. Let's do the setup.

  • First, we have to create one static folder in our root directory.
  • Now inside our project main settings.py we just need to add one line of code

STATIC_ROOT = BASE_DIR / 'static/'

  • Now run this command (make sure your virtual env is activated) python manage.py collectstatic. With this command, Django will copy all static assets into your Root Static Folder. In our case, it's the Static folder.
  • Now one setup is left, which is nginx,

Go to your nginx django.conf file and add the below code after the location code block

location /static/ { autoindex on; alias /home/ubuntu/PROJECT_FOLDER/static/; }
  • Now restart nginx server - sudo service nginx restart.

  Never miss a story from us, get weekly updates in your inbox.