Deploy a Django-based App in Amazon Lighsail

Production ready Django App in Amazon Lightsail

This article is based in this documentation page and this video where Mike Coleman takes us how to deploy a Django application on Amazon Lightsail. It was also considered two articles from Bitnami (Getting started with Django, and Deploy a Django project).

1- Start by creating an instance.


2- Select the region (in my case London), the Django blueprint which has everything one needs already installed to run the Django app (Python, virtualenv, Django), how much we want to pay for it (in this case $5) and give it a name.

3- The instance is now up and running. Now we need to go in and install our application and we do that by starting an ssh session.

4- The directories mentioned in the documentation and in the video aren’t created by the blueprint. Let’s create a new folder to store your Django projects, such as the /home/bitnami/projects directory, and give write permissions for the current system user (as mentioned here).


5- Start a Django project (django-admin.py startproject tutorial)


6- Go into the tutorial project directory, and create a new hello_world app (python manage.py startapp hello_world)


7- In tutorial/hello_world/views.py add the following code
from django.http import HttpResponse

def index(request):
return HttpResponse("Hello, world")

Note: Click Esc, type :wq! , and press Enter to save and quit Vim.

8- In tutorial/hello_world/urls.py add the following code
from django.urls import path
from . import views

urlpatterns = [
path('', views.index, name='index'),
]

9- In tutorial/tutorial/urls.py replace the code with this one
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
path('', include('hello_world.urls')),
path('admin/', admin.site.urls),
]`

10- By default, Apache is using port 80 on your Lightsail instance, so we’ll run the Django web server on port 8000. To be able to access the website, we’ll need to open port 8000 on the Lightsail firewall.

In the Lighsail homepage, click in the name of the instance and from the menu go to “Networking”. Under “Firewall” add another rule with 8000 in Port range.

11- Now, in tutorial/turorial/settings.py add the public IP address of your instance in ALLOWED_HOSTS.

12- Go to the root of the project, / tutorial, and run Django’s web server on port 8000
python manage.py runserver 0.0.0.0:8000

We can now see “Hello, world”, which confirms that the application is running. Note that this is a development server (It’s not recommended to run production applications using Django’s built-in server).

So, as next step, what we want to do is to take that application and get it hosted in the built in Apache server.

We’ll do this by configuring the application to use Web Services Gateway Interface (WSGI), and then create an Apache virtual host (vHost). To do this, tried initially Approach B: Self-Contained Bitnami Installations but stumbled into a roadblock. So, I’ve gone with Approach A: Bitnami Installations Using System Packages.

13- To serve the application through the Apache web server with the mod_wsgi module, go let’s start by editing /tutorial/tutorial/wsgi.py . Click Esc, type :1,$d and press Enter to select all, and delete the existing contents. Then, insert the following code (replace tutorial with the name of your project)
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tutorial.settings')
application = get_wsgi_application()

14- The Bitnami installation comes with predefined HTTP and HTTPS virtual hosts for running Django projects with the mod_wsgi module. To enable them, follow the steps below:

14.1- Copy the files to remove the .disabled suffix:
cd /home/bitnami/stack/apache2/conf/vhosts/

sudo sample-vhost.conf.disabled tutorial-vhost.conf

sudo cp sample-https-vhost.conf.disabled tutorial-https-vhost.conf

14.2- Restart Apache for the changes to be taken into effect:
cd /home/bitnami/stack

sudo ./ctlscript.sh restart apache

15- To make the Django project properly work in your web browser, some additional changes may be needed. Open the settings.py file for the Django project and follow these steps:
15.1- Disable DEBUG mode:
DEBUG = False

15.2- Set the ALLOWED_HOSTS setting for making the Django project remotely accessible:
ALLOWED_HOSTS = ['*'] # If you want public access

15.3- Set STATIC_URL and STATIC_ROOT to serve static files:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# to use os you’ll need to also import it in the begining of the file import os

15.4- Build static files executing the following command:
python manage.py collectstatic --noinput

15.5- Create a Django superuser:
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser


16- If the predefined virtual hosts are not available to you, or if you prefer to apply a custom configuration, follow the steps below:

16.1- Create and edit the /home/bitnami/stack/apache2/conf/vhosts/tutorial-http-vhost.conf file, delete the current content (Esc, type :1,$d and press Enter to select all, and delete the existing contents) and add the following lines (replace tutorial with the name of your project)

<IfDefine !IS_TUTORIAL_LOADED>
  Define IS_TUTORIAL_LOADED
  WSGIDaemonProcess tutorial python-home=/home/bitnami/stack/python python-path=/home/bitnami/projects/tutorial
</IfDefine>
<VirtualHost 127.0.0.1:80 _default_:80>
  ServerAlias *
  WSGIProcessGroup tutorial
  Alias /robots.txt /home/bitnami/projects/tutorial/static/robots.txt
  Alias /favicon.ico /home/bitnami/projects/tutorial/static/favicon.ico
  Alias /static/ /home/bitnami/projects/tutorial/static/
  <Directory /home/bitnami/projects/tutorial/static>
    Require all granted
  </Directory>
  WSGIScriptAlias / /home/bitnami/projects/tutorial/tutorial/wsgi.py
  <Directory /home/bitnami/projects/tutorial/tutorial>
    <Files wsgi.py>
      Require all granted
    </Files>
  </Directory>
</VirtualHost>

16.2- Create and edit the /home/bitnami/stack/apache2/conf/vhosts/tutorial-https-vhost.conf file and add the following lines (replace tutorial with the name of your project)

<IfDefine !IS_TUTORIAL_LOADED>
  Define IS_TUTORIAL_LOADED
  WSGIDaemonProcess tutorial python-home=/home/bitnami/stack/python python-path=/home/bitnami/projects/tutorial
</IfDefine>
<VirtualHost 127.0.0.1:80 _default_:80>
  ServerAlias *
  SSLEngine on
  SSLCertificateFile "/home/bitnami/stack/apache2/conf/bitnami/certs/server.crt"
  SSLCertificateKeyFile "/home/bitnami/stack/apache2/conf/bitnami/certs/server.key"
  WSGIProcessGroup tutorial
  Alias /robots.txt /home/bitnami/projects/tutorial/static/robots.txt
  Alias /favicon.ico /home/bitnami/projects/tutorial/static/favicon.ico
  Alias /static/ /home/bitnami/projects/tutorial/static/
  <Directory /home/bitnami/projects/tutorial/static>
    Require all granted
  </Directory>
  WSGIScriptAlias / /home/bitnami/projects/tutorial/tutorial/wsgi.py
  <Directory /home/bitnami/projects/tutorial/tutorial>
    <Files wsgi.py>
      Require all granted
    </Files>
  </Directory>
</VirtualHost>

17- Restart the Apache server:
cd /home/bitnami/stack

sudo ./ctlscript.sh restart apache

18- Once that’s all done, you can go to your instance’s IP address and you’ll see something like this

Registration disabled