Search code examples
djangodockerpython-requestsfastapi

Failed to establish a new connection: [Errno 111] Connection refused Django_in_Docker + FastAPI_in_Docker


I deploy 2 applications in different Docker container: 1 application-Django 2 application-FastAPI I have view function "view_request" in my Django-app, which make request to FastAPI app. From my browser Chrome I make request to Django endpoint, which run "view_request" function in Django, which make request to FastAPI app. Then I have this:

ConnectionError HTTPConnectionPool(host='127.0.0.1', port=8100): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f146c6a61c0>: Failed to establish a new connection: [Errno 111] Connection refused'))

FastAPI app This container run by command: docker run -d --name fast_api -p 8100:8000 fast_api Dokerfile:

FROM python:3.8.10-slim

# 
WORKDIR /code

# 
COPY ./requirements.txt /code/requirements.txt

# 
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt

# 
COPY ./app /code/app

# 
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8100"]

file main.py:

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def root():
    return {
        "message": (
            "Hello World !!!!!!"
            "This message from FastApi!"
        )
    }


if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8100)

Django app This container run by command: docker run --name sim_app -it -p 8000:8000 sim_app

Dokerfile:

FROM python:3.8.10-slim

RUN mkdir /app

COPY requirements.txt /app

RUN pip3 install -r /app/requirements.txt --no-cache-dir

COPY simple_app/ /app

WORKDIR /app

CMD ["python3", "manage.py", "runserver", "0:8000"] 

file views.py:

def view_request(request):
    template = 'api/index.html'
    data = requests.get(
        url='http://127.0.0.1:8100'
    )
    ready = data.json()
    
    context = {
        'ready': ready
    }
    return render(request, template, context)

Solution

  • The 127.0.0.1 inside the container refers to the container itself, not the host machine. You ran the containers separately and if you want Django app to communicate with FastAPI app, then

    • You can use Docker Networking. As this allows containers to communicate with each other in a network.
    • Or you can deploy multiple containers by using Docker compose

    Steps

    • change 127.0.0.1 into fast_api, as this is the container name
    def view_request(request):
        template = 'api/index.html'
        data = requests.get(
            url='http://fast_api:8100'
        )
        ready = data.json()
        
        context = {
            'ready': ready
        }
        return render(request, template, context)
    
    • Create a network
    docker network create my_app_network
    
    • Then run docker containers within that network
    docker run --network my_app_network --name sim_app -p 8000:8000 sim_app
    docker run --network my_app_network --name fast_api -p 8100:8100 fast_api
    

    Now sim_app will able to communicate with fast_api

    You can also use docker-compose

    version: '3'
    
    services:
      sim_app:
        build:
          context: .
          dockerfile: ./Dockerfile-sim
        ports:
          - '8000:8000'
        depends_on:
          - fast_api
    
      fast_api:
        build:
          context: .
          dockerfile: ./Dockerfile-fast_api
        ports:
          - '8100:8100'
    

    Hope this helps