Skip to content

Jayanth-MKV/django-docker-awslambda-deploy-guide

Repository files navigation

Django PIP Python AWS Postgres

Django URL Shortener (Enhanced)

Table of Contents

🌟 Introduction

Django URL Shortener is a web application for shortening URLs. This project includes additional CRUD operations, search functionality, and is containerized using Docker for deployment to AWS Lambda.

πŸ›  Added Functionality

Initially cloned from

https://github.com/mmedoo/django-url-shortener.git
  • CRUD Operations: Added functionality to Create, Read, Update, and Delete shortened URLs (Like TODOIST).
  • Search Functionality: Implemented a search feature to find URLs based on keywords.
  • Login Functionality: Will be implemented if time permits

βš™οΈ Installation

To get the project up and running locally on the machine, follow these steps:

  1. Clone the repository:

    git clone <url>
    cd django-url-shortener
  2. Set up a virtual environment:

    python3 -m venv venv
    source venv/bin/activate
    # windows
    .\venv\Scripts\activate
  3. Install dependencies:

    pip install -r requirements.txt
  4. Run migrations:

    python manage.py makemigrations url_shortener
    python manage.py makemigrations
    python manage.py migrate
  5. Start the development server:

    python manage.py runserver

πŸš€ Usage

Shorten a URL

  1. Navigate to the home page.
  2. Enter the URL you want to shorten in the provided form.
  3. Click the "Shorten URL" button.
  4. The shortened URL will be displayed on the screen.

Retrieve a URL

  1. Enter the shortened key in the URL path (e.g., http://localhost:8000/<shortened-key>).
  2. You will be redirected to the original URL.

Manage URLs

  1. Use the provided CRUD interfaces to manage the shortened URLs.
  2. Use the search functionality to find specific URLs.

πŸ“¦ Dependencies

  • Django==5.0.7
  • psycopg2-binary
  • python-dotenv
  • zappa

πŸ”§ Configuration

Database

By default, this project uses PostgreSQL hosted on AWS RDS. We can configure the database by updating the DATABASES setting in settings.py.

.env setup

To run the application the database need to be setup, which is hosted on AWS RDS. We can configure the database by updating these.

RDS_USERNAME = ''
RDS_PASSWORD = ''
RDS_HOSTNAME = ''
RDS_DB_NAME = ''

If you want to use the default sqlite database: In app.settings.py - change this

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

🐳 Dockerization

The application has been Dockerized to ensure consistent deployment and execution across different environments.

Dockerfile

FROM python:3.11.9-slim AS stage-1
COPY . /django_lambda/
WORKDIR /django_lambda
RUN pip install pipenv
RUN pipenv install -r requirements.txt
RUN pipenv run zappa package -o /django_zappa.zip

FROM python:3.11.9-slim
COPY --from=stage-1 django_zappa.zip /django_zappa.zip
RUN apt-get update && apt-get install -y unzip
RUN pip install awslambdaric boto3
RUN unzip /django_zappa.zip -d /app/
WORKDIR /app

# IMPORTANT TO SET THIS
ENV PYTHONPATH "${PYTHONPATH}:/app"
ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie
COPY entry.sh /
RUN chmod 755 /usr/bin/aws-lambda-rie /entry.sh
ENTRYPOINT [ "/entry.sh" ]
CMD ["handler.lambda_handler"]

Here for a django application to run on a serverless machine ( here AWS Lambda ) it needs to be configured accordingly so that be hosted. Thi spart is done by an opensource tool called zappa. zappa needds to be configured inside a virtual env hence pyenv is used . Instead of using zappa locally, here we did it inside the docker image.

The image building happens in two stages. First, the zappa package for the django application is created, this will be a zip file. Then create our final image for hosting this container on AWS lambda. Note that the first stage is used for building the zappa package and is not part of the final image.

Now, as we have the final image - for hosting it it need to be compatible with the AWS Lambda run time. Thus we use awslambdaric to implement the Lambda Runtime API, allowing to seamlessly extend our final image to be Lambda compatible.

To make it easy to locally test Lambda functions packaged as container images we use AWS Lambda Runtime Interface Emulator aws-lambda-rie.

Run this final image locally and test

docker build -f Dockerfile.aws -t urlapp .
docker run -p 8000:8080 --name app urlapp

The way we test a Django web server differs from how we would test a Lambda function. The command to test our function invocation is as follows:

curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"path": "/", "httpMethod": "GET", "requestContext": {}, "body": null}'

☁️ Deployment to AWS Lambda

The application is deployed to AWS Lambda using Zappa, which converts the Django app to a serverless architecture.

Building and Running Docker Image For Hosting

  1. Build the Docker image:

    docker build -f Dockerfile.aws -t urlapp .
  2. Tag the Docker image:

    docker tag urlapp:latest 339713069346.dkr.ecr.ap-southeast-2.amazonaws.com/urlapp:latest
  3. Push the Docker image to ECR:

    docker push 339713069346.dkr.ecr.ap-southeast-2.amazonaws.com/urlapp:latest
  4. Deploy the Application:

    zappa deploy dev -d 339713069346.dkr.ecr.ap-southeast-2.amazonaws.com/urlapp:latest

Zappa takes care of the AWS Gateway here.

SOME COMMANDS FOR REFERENCE

  1. Install Zappa:

    pip install zappa
  2. Initialize Zappa:

    zappa init
  3. Deploy the Application:

    zappa deploy dev -d 339713069346.dkr.ecr.ap-southeast-2.amazonaws.com/urlapp:latest
  4. Update the Application:

    zappa update dev -d 339713069346.dkr.ecr.ap-southeast-2.amazonaws.com/urlapp:latest

Configuration and Deployment Details

  • Dockerize Application: Containerized the Django application using a multi-stage Dockerfile.
  • Zappa: Used Zappa to package and deploy the application to AWS Lambda.

πŸ”— References

❗️ Troubleshooting

Common Issues

  • Server not starting: Ensure all dependencies are installed and the database migrations have been applied.
  • Invalid URL: Make sure the URL entered is valid and follows the correct format.

Releases

No releases published

Packages

No packages published