- π Introduction
- π Added Functionality
- βοΈ Installation
- π Usage
- π¦ Dependencies
- π§ Configuration
- π³ Dockerization
- βοΈ Deployment to AWS Lambda
- π References
- βοΈ Troubleshooting
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.
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
To get the project up and running locally on the machine, follow these steps:
-
Clone the repository:
git clone <url> cd django-url-shortener
-
Set up a virtual environment:
python3 -m venv venv source venv/bin/activate
# windows .\venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
-
Run migrations:
python manage.py makemigrations url_shortener python manage.py makemigrations python manage.py migrate
-
Start the development server:
python manage.py runserver
- Navigate to the home page.
- Enter the URL you want to shorten in the provided form.
- Click the "Shorten URL" button.
- The shortened URL will be displayed on the screen.
- Enter the shortened key in the URL path (e.g.,
http://localhost:8000/<shortened-key>
). - You will be redirected to the original URL.
- Use the provided CRUD interfaces to manage the shortened URLs.
- Use the search functionality to find specific URLs.
- Django==5.0.7
- psycopg2-binary
- python-dotenv
- zappa
By default, this project uses PostgreSQL hosted on AWS RDS. We can configure the database by updating the DATABASES
setting in settings.py
.
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',
}
}
The application has been Dockerized to ensure consistent deployment and execution across different environments.
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}'
The application is deployed to AWS Lambda using Zappa, which converts the Django app to a serverless architecture.
-
Build the Docker image:
docker build -f Dockerfile.aws -t urlapp .
-
Tag the Docker image:
docker tag urlapp:latest 339713069346.dkr.ecr.ap-southeast-2.amazonaws.com/urlapp:latest
-
Push the Docker image to ECR:
docker push 339713069346.dkr.ecr.ap-southeast-2.amazonaws.com/urlapp:latest
-
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.
-
Install Zappa:
pip install zappa
-
Initialize Zappa:
zappa init
-
Deploy the Application:
zappa deploy dev -d 339713069346.dkr.ecr.ap-southeast-2.amazonaws.com/urlapp:latest
-
Update the Application:
zappa update dev -d 339713069346.dkr.ecr.ap-southeast-2.amazonaws.com/urlapp:latest
- Dockerize Application: Containerized the Django application using a multi-stage Dockerfile.
- Zappa: Used Zappa to package and deploy the application to AWS Lambda.
- Ian Whitestone's guide on Zappa and Docker
- Mark Gituma's guide on deploying Django Docker images to AWS Lambda
- AWS Lambda Python Image Instructions
- YCombinator discussion on AWS Lambda and Docker
- Zappa GitHub repository
- 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.