Search code examples
djangoamazon-web-servicesdockerdockerfileaws-fargate

Expose host port 80 of a Dockerized Django app deployed on AWS Fargate


I have a very simple Django rest framework (DRF) app that is dockerized and deployed on AWS ECS with Fargate. I created a security group to expose the port 8000 on the inbound rules and was able to see the app at public IP 12.34.56:78:8000/

I wanted to have the app run on port 80, but don't know how to. Do I need to expose 80 on the Dockerfile and specify that port when creating the task definition? Or do I need to set up nginx to pass HTTP requests to port 8000 internally?

Dockerfile:

# Pull base image
FROM python:3.12

# Set environment variables
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Set work directory
WORKDIR /app

# Install dependencies
COPY ./requirements.txt .
RUN pip install -r requirements.txt

# Copy project
COPY . .

# Expose the Django development server port
EXPOSE 8000

# # Start the Django development server
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Task definition:

{
    "taskDefinitionArn": "arn:aws:ecs:us-west-1:123:task-definition/app-task:12",
    "containerDefinitions": [
        {
            "name": "container-name",
            "image": "dockerhub/app:latest",
            "cpu": 0,
            "portMappings": [
                {
                    "name": "default",
                    "containerPort": 8000,
                    "hostPort": 8000,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "essential": true,
            "environment": [],
            "mountPoints": [],
            "volumesFrom": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-create-group": "true",
                    "awslogs-group": "/ecs/app-api-task",
                    "awslogs-region": "us-west-1",
                    "awslogs-stream-prefix": "ecs"
                }
            }
        }
    ],
    ....

}

Solution

  • Well, you can do this in several different ways, but following your line of reasoning:

    You can change the port of your application and also in the Dockerfile to port 80 and configure the same port for the sec-group.

    Another way to do this is to add an ALB which will forward requests on port 80 to the container on port 8000.

    Another possibility is to create another container with nginx, and configure it as a reverse proxy for your application, this last way is a little more difficult to do, see this article.