Skip to content
Go back

Django Todo App Deployment - EC2, Virtual Environments, and Docker

Published:

Add 2 Inbound rule to your EC2 instance.

out

1. Connect to Your EC2 Instance via SSH

ssh -i ~/.ssh/aws-janak.pem  [email protected]

2. Prepare the EC2 Server Environment

Once connected via SSH to your EC2 instance:

  1. Update System Packages:

    sudo apt update
    sudo apt upgrade -y
  2. Install Essential Software:

    sudo apt install python3.13 python3.13-venv -y
    • python3.13-venv: For creating isolated Python environments.

Deploying with a Python Virtual Environment 🐍

1. Clone Your Django Project

git clone https://github.com/shreys7/django-todo.git
cd django-todo

2. Create and Activate Virtual Environment (on EC2)

  1. Create:
    python3 -m venv venv
  2. Activate:
    source venv/bin/activate
    Your prompt should now show (venv) at the beginning, indicating the virtual environment is active.

out

If you want to Deactivate the current virtual environment(Dont do)

deactivate

Ensure (venv) disappears from your prompt.

3. Configure Django Settings

Install Core Django:

pip install django

You need to tell Django about your EC2 instance’s public IP and prepare it for a production-like environment.

  1. Open settings.py:
    nano todoApp/settings.py
  2. Set DEBUG = False: Never run with DEBUG = True in production! It exposes sensitive information.
  3. Add your EC2 Public IP to ALLOWED_HOSTS: Find ALLOWED_HOSTS = [] and add your instance’s public IP.
    ALLOWED_HOSTS = ['44.202.47.32']
    # Example for all: ALLOWED_HOSTS = ['*']
    If you get a domain name later, add it here too: ['your_instance_public_ip', 'your-domain.com'].
  4. Configure STATIC_ROOT: Ensure these lines are present (add import os at the top if missing):
    import os
    # ... other settings ...
  5. Save and Exit: Press Ctrl+X, then Y, then Enter.

out

6. Prepare Database and Static Files

  1. Collect Static Files:
    python3 manage.py collectstatic
    Type yes when prompted. This gathers all static assets (CSS, JS, images) into the staticfiles folder.
  2. Apply Migrations:
    python3 manage.py makemigrations # Only needed if you made model changes
    python3 manage.py migrate
  3. Create Superuser:
    python3 manage.py createsuperuser

out

7. Test with Django’s Development Server

This is just to confirm your app runs before setting up production servers.

  1. Run the server:
    python3 manage.py runserver 0.0.0.0:8000
    You’ll see warnings about it being a development server, which is expected.
  2. Access in browser: Open your browser and go to http://44.202.47.32:8000/. If you get a DisallowedHost error, double-check that your EC2 Public IP is correctly added to ALLOWED_HOSTS in settings.py. Make sure Port 8000 is open in your EC2 instance’s Inbound Security Group.

out

8. Run in Background with nohup (Temporary)

To keep the development server running even after you close your SSH session:

  1. Stop the current runserver (if running) by pressing Ctrl+C.
  2. Run with nohup:
    nohup python3 manage.py runserver 0.0.0.0:8000 &
    You’ll see a message about output being redirected to nohup.out. You can check it with tail -f nohup.out. To stop it later: ps aux | grep 'runserver' | grep -v 'grep' to find the PID, then kill <PID>.

out

Part 3: Containerizing with Docker

Docker provides a consistent and isolated environment for your app, making deployments more reliable.

1. Create Dockerfile and .dockerignore

# .dockerignore
venv/
__pycache__/
*.pyc
.git/
.gitignore
.DS_Store
nohup.out
db.sqlite3

2. Build the Docker Image

On your EC2 instance, in your project’s root:

sudo docker build -t django-todo-app .

3. Run the Docker Container

To run your app in a Docker container in the background:

sudo docker run -d -p 7777:7777 django-todo-app

4. Verify and Access Your Dockerized App

  1. Check if the container is running:
    sudo docker ps
    You should see your django-todo-app container listed with a Status of “Up…”.

out

  1. Access in browser: Ensure Port 8001 is open in your EC2 Security Group. Then, open your web browser and go to http://44.202.47.32:7777/todos/.

out


Prepare Your Local Project for Deployment

  1. Generate requirements.txt (on your LOCAL machine):
    • Navigate to your project’s root on your local machine.
    • If you have a local virtual environment, activate it.
    • Run:
      pip freeze > requirements.txt

out

Install Dependencies

  1. Install from requirements.txt:
    pip install -r requirements.txt
    If pip command doesn’t work directly (e.g., Command 'pip' not found), use python3 -m pip install -r requirements.txt instead.

out


What’s Next for Production?

While your app is now accessible, remember the warnings about using the Django development server. For a truly production-ready setup, you would:

  1. Replace runserver with Gunicorn: Update your Dockerfile’s CMD to use Gunicorn.
  2. Implement Nginx as a Reverse Proxy: Configure Nginx on your EC2 instance to serve static files directly and forward dynamic requests to Gunicorn. This is crucial for performance and security.
  3. Use a Production Database: Migrate from SQLite to a robust database like PostgreSQL, ideally using AWS RDS for managed services.
  4. Set up HTTPS (SSL/TLS): Secure your application with an SSL certificate (e.g., using Certbot with Let’s Encrypt).
  5. Environment Variables: Store sensitive data (like Django’s SECRET_KEY, database credentials) using environment variables or AWS Secrets Manager, not directly in settings.py.

Suggest Changes

Previous Post
Setting static IP and Connect to Ubuntu Linux VM via SSH form host OS with Key-Based Authentication.
Next Post
.com.np Domain + Cloudflare + Netlify (Adding domain and subdomain to your netlify hosted project) - Full Configuration Guide