Deployment on EC2

To deploy a Django application on an Amazon EC2 instance, you can follow these steps:

Configure an EC2 instance

Launch an EC2 instance:

  • Go to the EC2 console and launch a new instance. Choose an Amazon Linux 2 or Ubuntu AMI (preferred for compatibility with Django).
  • Configure the instance type (you can start with a t2.micro instance if it's for testing).
  • Create and download a new key pair (or use an existing one).
  • Configure security group rules to open the necessary ports:
    • Port 22 for SSH.
    • Port 80 for HTTP.
    • Port 443 for HTTPS (optional if using SSL).
  • Launch the instance.

Connect to the instance: Use SSH to connect to your instance:

ssh -i /path/to/your-key.pem ec2-user@<your-ec2-public-ip>  # For Amazon Linux
ssh -i /path/to/your-key.pem ubuntu@<your-ec2-public-ip>     # For Ubuntu

Install dependencies

Update the system:

sudo apt update && sudo apt upgrade -y  # For Ubuntu

Install Python, pip, and virtualenv:

sudo apt install python3-pip python3-dev libpq-dev nginx curl -y
sudo pip3 install virtualenv

Install PostgreSQL (optional, if you're using PostgreSQL):

sudo apt install postgresql postgresql-contrib -y

Configure PostgreSQL (optional):

Create a database and user for your Django application:

sudo -u postgres psql
CREATE DATABASE mydb;
CREATE USER myuser WITH PASSWORD 'mypassword';
ALTER ROLE myuser SET client_encoding TO 'utf8';
ALTER ROLE myuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myuser SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;
\q

Configure Django

Clone your Django project or create a new one.

git clone <your-repo-url>
cd <your-project-directory>

Set up a virtual environment:

virtualenv venv
source venv/bin/activate

Install the project dependencies:

pip install -r requirements.txt

Set up environment variables:

Make sure to configure the environment variables in your settings.py file like this:

DEBUG = False
ALLOWED_HOSTS = ['<your-ec2-public-ip>', 'your-domain.com']

Configure the database (if using PostgreSQL) in settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydb',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '',
    }
}

Collect static files:

python manage.py collectstatic

Migrate the database:

python manage.py migrate

Configure Gunicorn 1 2

Install Gunicorn:

pip install gunicorn

Test Gunicorn for your application:

gunicorn --workers 3 <your_project_name>.wsgi:application

Set up Gunicorn as a systemd service:

Create the file /etc/systemd/system/your-deployment.service:

sudo nano /etc/systemd/system/your-deployment.service

Add the service configuration:

[Unit]
Description=gunicorn daemon
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/<your-project-directory>
ExecStart=/home/ubuntu/<your-project-directory>/venv/bin/gunicorn --workers 3 --bind :8080 <your_project_name>.wsgi:application
# EnvironmentFile=/home/ubuntu/<your-project-directory>/.env

[Install]
WantedBy=multi-user.target

Start and enable the Gunicorn service:

sudo systemctl enable your-deployment.service
sudo systemctl start your-deployment.service

(optional) Edit your-deployment.service

After editing, reload the services:

sudo systemctl daemon-reload

Restart the service

sudo systemctl restart your-deployment.service

View the status

sudo systemctl status your-deployment.service

To enable the service at each reboot

sudo systemctl enable your-deployment.service

To disable the service at each reboot

sudo systemctl disable your-deployment.service

Configure Nginx

Set up Nginx to serve your application:

Create a configuration file in /etc/nginx/sites-available/:

sudo nano /etc/nginx/sites-available/<your-project-name>

Add this configuration:

server {
    listen 80;
    server_name <your-ec2-public-ip> your-domain.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/ubuntu/<your-project-directory>;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/ubuntu/<your-project-directory>/gunicorn.sock;
    }
}

Enable the configuration and restart Nginx:

sudo ln -s /etc/nginx/sites-available/<your-project-name> /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx

Configure the Firewall

Set up UFW to allow SSH, HTTP, and HTTPS connections:

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

(Optional) Set up SSL with Let's Encrypt

Install Certbot:

sudo apt install certbot python3-certbot-nginx -y

Generate an SSL certificate:

sudo certbot --nginx -d your-domain.com

Verify automatic renewal:

sudo certbot renew --dry-run

Conclusion

With this setup, your Django application should be available on your domain or public EC2 IP address. Be sure to monitor performance and security as your application scales.


  1. Gunicorn. Running gunicorn - gunicorn 23.0.0 documentation. URL: https://docs.gunicorn.org/en/latest/run.html

  2. Jimmy Tron. Demystifying django deployment with gunicorn and ubuntu service daemons. URL: https://medium.com/@otienojames9/demystifying-django-deployment-with-gunicorn-and-ubuntu-service-daemons-a951900d8871