Deploy Django + PostgreSQL on EC2 using Apache2 from scratch
It’s fun to build apps as personal projects, but what if you want it to deploy it and showcase it to others? And not only that it should be able to handle multiple requests simultaneously. Well, in this article we’ll do this. Create Django apps, use PostgreSQL as a database and use Apache2 for handling multiple requests and some tips for logging and debugging errors.
Setup EC2 instance
Launch a new Instance on AWS EC2 using the following configs:
- OS: Ubuntu 18.04 LTS
- Any instance type, we’ll choose t2.medium
- Add Storage 20GB, it’ll be sufficient for now
- In Security group, add rule with Type: HTTP, Port Range: 80, Source: Custom and 0.0.0.0/0, ::/0
Launch the instance and SSH into it.
Setup PostgreSQL
- Install PostgreSQL:
sudo apt-get updatesudo apt-get install python-dev libpq-dev postgresql postgresql-contrib
2. Now, let’s setup PostgreSQL,
sudo su — postgrespsqlCREATE DATABASE djangodemodb;CREATE USER adesh WITH PASSWORD ‘mysecretpass’;GRANT ALL PRIVILEGES ON DATABASE djangodemodb TO adesh;\qexit
Using these commands sequentially, you’ll create a database named ‘djangodemodb’ and a new user ‘adesh’ with ‘mysercretpass’ as password. You also need to grant privileges to ‘adesh’ user for ‘djangodemodb’ database. Finally, you exit out of the psql shell using \q.
Setup Django
First we’ll set up the virtual environment for Django so that it’s easily deployable on EC2.
- Create a directory djangodemo and create a virtualenv using python3:
mkdir djangodemo
cd djangodemo
virtualenv -p python3 djangodemo
2. Install Django 2.2. We’ll work on this as it’s the LTS version.
source djangodemo/bin/activate
pip install django==2.2
3. Then create a Django project:
python -m django startproject djangodemo_UI
4. Test if the Django server is running, it will be at 127.0.0.01:8000
python manage.py makemigrations && python manage.py migratepython manage.py runserver
5. In the settings.py file change the following:
ALLOWED_HOSTS = [‘*’]Change DATABASES to this:DATABASES = {‘default’: {‘ENGINE’: ‘django.db.backends.postgresql_psycopg2’,‘NAME’: ‘djangodemodb’,‘USER’: ‘adesh’,‘PASSWORD’: ‘mysecretpass’,‘HOST’: ‘localhost’,‘PORT’: ‘’,}}
6. Install psycopg2 to help Django interact with PostgreSQL.
pip install psycopg2
If you get an error, try
pip install psycopg2-binary
7. Create superuser for the admin dashboard, it will ask for username and password:
python manage.py createsuperuser
Setup Apache2
- Install Apache2:
sudo apt-get updatesudo apt-get install python3-pip apache2 libapache2-mod-wsgi-py3
2. Change the configs of 000-default.conf:
vim /etc/apache2/sites-available/000-default.conf
File location: /etc/apache2/sites-available/000-default.conf
Change the following in the above config:
Change path/to/your/djangodemo_UI to your root djangodemo directory
Change path/to/your/djangodemo_UI/wsgi/folder to your path containing the wsgi.py file in djangodemo_UI/djangodemo_UI
Change path/to/your/djangodemo/virtualenv to your path to the djangodemo virtual environment we created
3. Enable MPM workers to handle multiple requests in apache2.conf:
vim /etc/apache2/apache2.conf
File location: /etc/apache2/apache2.conf
Add the following lines at the end of the file. These need to be changed as per your Django app memory consumption and traffic.
4. Change the permissions for ‘djangodemo_UI’ directory using:
sudo chown :www-data djangodemo_UI
5. Now, restart the Apache2 server:
sudo service apache2 restart
Now go to the IPv4/Public URL of your EC2 instance and you’ll see you Django app running.
Logging and Debugging
It is very difficult to debug errors on Apache2. For that we’ll configure Django to log errors separately. Add the following to settings.py:
Check this file for potential errors, or you can check the Apache2 logs using:
tail -n 100 /var/log/apache2/error.log
Also, use DEBUG=False in settings.py in production. This could also help in finding errors in the logs.
Notes
- Check the Security Group rules. Allow port 80 for HTTP
- Use correct paths in 000-default.conf file
- Check if correct dependencies are installed in the virtual environment.
- Check for the correct PostgreSQL configuration.
- Check for correct ‘static’ and ‘media’ directories.
You can find the Github repo here