简体   繁体   中英

Docker run error - Failed to find Flask application or factory in module "app". Use "FLASK_APP=app:name to specify one

trying to dockerize this flask app... running the following

docker build --tag flask-website .

works, output successfully built, successfully tagged.

edit: the next command works

$ docker run --publish 5000:5000 flask-website
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off

ok, so then I run curl localhost:5000

which gives this error

curl: (7) Failed to connect to localhost port 5000: Connection refused

ok straight forward enough, so then I try this

docker-compose up

and this results

Creating network "app_default" with the default driver
Creating app_web_1 ... done
Attaching to app_web_1
web_1  |  * Environment: production
web_1  |    WARNING: This is a development server. Do not use it in a production deployment.
web_1  |    Use a production WSGI server instead.
web_1  |  * Debug mode: off

however trying to navigate to localhost:5000 I get

This site can’t be reachedThe webpage at http://localhost:5000/ 
might be temporarily down or it may have moved permanently 
to a new web address.
ERR_SOCKET_NOT_CONNECTED

directory structure looks like this

├──app_folder/
    └── app/
    |    ├── static/
    |    |      └── css/
    |    |          └──app.css
    |    |      └── js/
    |    |          └──app.js
    |    └── templates/
    |    |   └── app.html
    |    |   └── subapp.html
    |    |   └── subapp1.html
    |    |   └── subapp2.html
    |    |   └── subapp3.html
    |    └── app.py
    |    └── util.py
    |    └── pickle_file.pickle
    |    └── requirements.txt
    |    └── Dockerfile
    |    └── Makefile
    |    └── docker-compose.yml

dockerfile looks like this

FROM python:3.8

ENV PYTHONUNBUFFERED=1

WORKDIR /

COPY requirements.txt requirements.txt
COPY . .

RUN pip install -r requirements.txt

# EXPOSE 5000

CMD [ "python", "-m" , "flask", "run", "--host=0.0.0.0"]

I had tried with EXPOSE 5000 uncommented and commented, making no difference

I also updated the directory structure and dockerfile, which got rid of the command line error I was seeing

docker-compose looks like this

version: "3.7"
services:
  web:
    image: flask-website:latest
    ports:
      - 5000:5000

I tried with the dockerfile, docker-compose, makefile, and requirements outside of the app directory and a slightly modified dockerfile on the WORKDIR line, that resulted in this error

Error: Failed to find Flask application or factory in module "app". Use "FLASK_APP=app:name to specify one.

not sure what else to try? I can run it locally with python -m flask run , but I cannot seem to dockerize it, seems like this should not be this difficult?

for completeness sake, app.py looks like this


from flask import Flask, request, jsonify
from flask import render_template, redirect
import json
import util

app = Flask(__name__, template_folder="templates", static_folder="static")


@app.route("/", methods=["GET", "POST"])
def index():
    return render_template("app.html")


@app.route("/predict_home_price", methods=["GET", "POST"])
def make_prediction():
   x = request.form["x"]
   y = float(request.form["y"]
   response = jsonify(
      {
         "prediction": util.prediction(x, y)
      }
   )
   response.headers.add("Access-Control-Allow-Origin", "*")
   
   return response

if __name__ == "__main__":
    from waitress import serve

    serve(app, host="0.0.0.0", port=5000)

util.py looks like this

import pickle
import pandas as pd
from scipy.special import inv_boxcox

# to run locally uncomment out the following
# with open("/path/to/pickle/app/pickle_mod.pickle", "rb") as f:
# to run in docker use the following
with open("app/pickle_mod.pickle", "rb") as f:
    __model = pickle.load(f)

def prediction(x, y):
   lambs = 0.205
   a = [[x, y]]
   cols = ["x", "y"]
   my_data = pd.DataFrame(data=a, columns=cols)
   pred = inv_boxcox(__model.predict(my_data)[0], lambs)
   return f"${round(pred)}"

if __name__ == "__main__":
   print(prediction(5, 4))

I have also tried both ways with the pickle import in util, same result - I thought because I was building it in a docker container that the second import was correct

I have also tried this block for app.run as well with the same result

if __name__ == "__main__":
    app.run()

I have ran a simple flask app in docker and here is the result. In your docker compose, you do not need to add the command: python app/app.py as this line was added in the Dockerfile.

The only thing you need in your Docker Compose is ports and image name

ok the following changes were required to get this image to build and the container to run

dockerfile:

FROM python:3.8

WORKDIR /

COPY requirements.txt requirements.txt

RUN pip install -r requirements.txt

COPY . .

EXPOSE 5000

ENTRYPOINT ["python", "./app.py"]

then the following change to the main application app.py

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

then to util.py, which had an error I did not see until running docker run [TAG]

with open("pickle_mod.pickle", "rb") as f:
    __model = pickle.load(f)

then run docker build -t [TAG] . then run docker-compose up

then navigate to localhost listening on port 5000 and there is the running container

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM