Saurabh
Saurabh

Reputation: 1662

How do access my flask app hosted in docker?

I am dockerizing my flask app for the first time, but I'm having an issue accessing it, these are steps I followed

my docker file looks like this

FROM ubuntu:18.04

RUN apt-get update -y && \
    apt-get install -y python3-pip python3-dev


# We copy just the requirements.txt first to leverage Docker cache
COPY ./requirements.txt /app/requirements.txt

WORKDIR /app

RUN pip3 install -r requirements.txt

COPY . /app

ENTRYPOINT [ "python3" ]

CMD [ "app.py" ]

Generated requirements through pip3 freeze command

sp@sp-H81M-S:~/Desktop/flask_app$ sudo docker build -t fynd_task_app:latest .
Sending build context to Docker daemon  297.5MB
Step 1/8 : FROM ubuntu:18.04
 ---> a2a15febcdf3
Step 2/8 : RUN apt-get update -y &&     apt-get install -y python3-pip python3-dev
 ---> Using cache
 ---> d9f20954e3a8
Step 3/8 : COPY ./requirements.txt /app/requirements.txt
 ---> Using cache
 ---> 37dd9000750d
Step 4/8 : WORKDIR /app
 ---> Using cache
 ---> 9faca0a1b18b
Step 5/8 : RUN pip3 install -r requirements.txt
 ---> Using cache
 ---> 080a6573557e
Step 6/8 : COPY . /app
 ---> e3a4e06df17f
Step 7/8 : ENTRYPOINT [ "python3" ]
 ---> Running in d2f5f3063f28
Removing intermediate container d2f5f3063f28
 ---> 6d7e7b86fa12
Step 8/8 : CMD [ "app.py" ]
 ---> Running in fa149cc83cd1
Removing intermediate container fa149cc83cd1
 ---> 14e53a2402c8
Successfully built 14e53a2402c8
Successfully tagged fynd_task_app:latest

And image also built successfully but when I m trying to run the container on 5000 port where flask should be serving

sp@sp-H81M-S:~/Desktop/flask_app$ sudo docker run -d -p 5000:5000 fynd_task_app:latest
739eddd6a289a6949a498829314ca01b3c6ef41b60e7a0ad6d66badbfd9e9379

I think its container getting exited and there's nothing served on localhost:5000

here's the app.py code

import cv2 as cv
import argparse
import sys
import numpy as np
import os.path
import flask
import io
from PIL import Image
from keras.preprocessing.image import img_to_array
from keras.applications import imagenet_utils
from werkzeug.utils import secure_filename
from flask import render_template



confThreshold = 0.5  
nmsThreshold = 0.4   
inpWidth = 416      
inpHeight = 416
image_name = "uploaded.jpg"
image_dir = str(os.getcwd())


classesFile = "coco.names";
classes = None
with open(classesFile, 'rt') as f:
    classes = f.read().rstrip('\n').split('\n')

modelConfiguration = "yolov3.cfg";
modelWeights = "yolov3.weights";



app = flask.Flask(__name__)


net = cv.dnn.readNetFromDarknet(modelConfiguration, modelWeights)
net.setPreferableBackend(cv.dnn.DNN_BACKEND_OPENCV)
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)




def getOutputsNames(net):
    layersNames = net.getLayerNames()
    return [layersNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]




def drawPred(classId, conf, left, top, right, bottom):
    cv.rectangle(frame, (left, top), (right, bottom), (255, 178, 50), 3)

    label = '%.2f' % conf

    if classes:
        assert(classId < len(classes))
        label = '%s:%s' % (classes[classId], label)

    labelSize, baseLine = cv.getTextSize(label, cv.FONT_HERSHEY_SIMPLEX, 0.5, 1)
    top = max(top, labelSize[1])
    cv.rectangle(frame, (left, top - round(1.5*labelSize[1])), (left + round(1.5*labelSize[0]), top + baseLine), (255, 255, 255), cv.FILLED)
    cv.putText(frame, label, (left, top), cv.FONT_HERSHEY_SIMPLEX, 0.75, (0,0,0), 1)






# Remove the bounding boxes with low confidence using non-maxima suppression
def postprocess(frame, outs):
    frameHeight = frame.shape[0]
    frameWidth = frame.shape[1]
    classIds = []
    confidences = []
    boxes = []
    for out in outs:
        for detection in out:
            scores = detection[5:]
            classId = np.argmax(scores)
            confidence = scores[classId]
            if confidence > confThreshold:
                center_x = int(detection[0] * frameWidth)
                center_y = int(detection[1] * frameHeight)
                width = int(detection[2] * frameWidth)
                height = int(detection[3] * frameHeight)
                left = int(center_x - width / 2)
                top = int(center_y - height / 2)
                classIds.append(classId)
                confidences.append(float(confidence))
                boxes.append([left, top, width, height])

    indices = cv.dnn.NMSBoxes(boxes, confidences, confThreshold, nmsThreshold)
    for i in indices:
        i = i[0]
        box = boxes[i]
        left = box[0]
        top = box[1]
        width = box[2]
        height = box[3]
        drawPred(classIds[i], confidences[i], left, top, left + width, top + height)
        print("Prediction Box: {}:{}:{}:{}".format(left,top,width,height))




@app.route('/')
def render_static():
    return render_template('index.html')


@app.route("/predict", methods=["POST"])

def predict():

    if flask.request.method == "POST":
        if flask.request.files.get("image"):

            file = flask.request.files["image"]
            file.save(image_name)
            frame = cv.imread(image_name)



            print(frame.shape)


            blob = cv.dnn.blobFromImage(frame, 1/255, (inpWidth, inpHeight), [0,0,0], 1, crop=False)

            net.setInput(blob)

            outs = net.forward(getOutputsNames(net))

            classIds = []
            confidences = []
            boxes = []
            frameHeight = frame.shape[0]
            frameWidth = frame.shape[1]
            predictions = []


            for out in outs:
                for detection in out:
                    scores = detection[5:]
                    classId = np.argmax(scores)
                    confidence = scores[classId]
                    if confidence > confThreshold:
                        center_x = int(detection[0] * frameWidth)
                        center_y = int(detection[1] * frameHeight)
                        width = int(detection[2] * frameWidth)
                        height = int(detection[3] * frameHeight)
                        left = int(center_x - width / 2)
                        top = int(center_y - height / 2)
                        classIds.append(classId)
                        confidences.append(float(confidence))
                        boxes.append([left, top, width, height])
                        points = [left, top, left + width, top + height]
                        label = '%.2f' % confidence
                        if classes:
                            assert(classId < len(classes))
                            label = '%s:%s' % (classes[classId], label)
                        info = {"bounding_boxes" : points, "class" : label}

                        predictions.append(info)


            t, _ = net.getPerfProfile()
            label = 'Inference time: %.2f ms' % (t * 1000.0 / cv.getTickFrequency())



            cv.putText(frame, label, (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255))

            cv.imwrite("tested.jpg", frame.astype(np.uint8))






    return render_template("show.html", user_image = image_name,prediction = predictions)      
    # return flask.jsonify(predictions)



if __name__ == "__main__":
    print("* Loading Keras model and Flask starting server...")
    app.run()

where is the issue?

Upvotes: 0

Views: 542

Answers (1)

kederrac
kederrac

Reputation: 17322

By default it runs on localhost (inside docker container), change it to app.run(host='0.0.0.0'). This tells your docker container to listen on a public IP ( so it can comunicate to docker container outside world) . (doc)

Upvotes: 1

Related Questions