skip to Main Content

So i have this flask app which trains a model for sentiment analysis and this is how I start the app.

if __name__ == '__main__':
    app.run(debug=False, host="0.0.0.0", port=5000)

The docker file is the following:

FROM python:3.9-slim-buster

WORKDIR /python-docker

COPY requirements.txt requirements.txt
COPY good_words.txt good_words.txt
COPY bad_words.txt bad_words.txt
COPY imdb_labelled.txt imdb_labelled.txt
COPY amazon_cells_labelled.txt amazon_cells_labelled.txt
COPY yelp_labelled_good.txt yelp_labelled_good.txt
RUN pip3 install -r requirements.txt

COPY . .

EXPOSE 5000

CMD [ "python3", "main.py", "-h", "0.0.0.0", "-p", "5000"]

I have this Node JS app from which I make a POST request to the flask server in order to analyse some data.

  const paragraphs = await Promise.all(
    result.paragraphs.map(async (paragraph) => {
      try {
        const response = await axios.post(
          url,
          JSON.stringify({ text: paragraph }),
          {
            headers: {
              "Content-Type": "application/json",
            },
          }
        );
        const sentimentResponse = parseFloat(response.data);
        if (sentimentResponse > threshold.positive) {
          return { paragraph: paragraph, sentiment: "Positive" };
        } else if (sentimentResponse < threshold.negative) {
          return { paragraph: paragraph, sentiment: "Negative" };
        } else {
          return { paragraph: paragraph, sentiment: "Neutral" };
        }
      } catch (error) {
        throw new AppError("Failed to retrieve Sentiments", 500);
      }
    })
  );
  return paragraphs;
};

The url is basically http://127.0.0.1:5000/sentiment which is the URL I am using in the flask app to listen to requests.

The interesting is that if i run this request from outside the NodeJS app, e.g. Postman, it works, but from the axios request it doesn’t.

What can i do?

2

Answers


  1. Chosen as BEST ANSWER
    backend:
    #other configurations
       networks:
                app_net:
                    ipv4_address: 172.16.238.2
    frontend:
    #other configurations
        networks:
                app_net:
                    ipv4_address: 172.16.238.3
    
    flask:
        #other configurations
        networks:
                app_net:
                    ipv4_address: 172.16.238.4
    
    networks:
        app_net:
            ipam:
                driver: default
                config:
                - subnet: "172.16.238.0/24"
    

  2. TL;DR
    You have 2 options:

    1. Change the url to http://host.docker.internal:5000/sentiment
    2. Put them both on the same network and communicate using that name.
    docker network create my-network
    docker run --name nodejs -d <nodejs> --network my-network <image>
    docker run --name flask -d <flask> --network my-network <image>
    

    When you’ll run axious.post("http://flask:5000") it should work.

    Explanation:
    The address "localhost" is depending on where you execute the command.
    When you run it from the host you access the container from the port you’ve opened and when you run it. But when you run it from a different container the "localhost" is referenced to the same container running it which the port is not open.

    This is how the solutions work:

    1. When you use host.docker.internal it means that you request the docker host which hosing the containers and it has the port bound to the destination container

    2. When you create a network it passes the request directly to the container.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search