0

I have a flask app, with Flask RestX, that works fine with flask run but has import issues with Docker. I've seen some questions and answers about this but they all involve Gunicorn, but I'm not using Gunicorn.

Here is my folder structure. I'm running the docker-compose file which uses the flask.dev.dockerfile as well as a Redis container.

enter image description here

So, I want to use my redis wrapper, RedisDatabase, from my database.py file. PyCharm inserts this as

from ivd_app.database import RedisDatabase

And the rest of the __init__.py file, in summary:

from flask import Flask, request
from flask_cors import CORS
from flask_restx import Api, Resource, fields

def create_app(db=None):
    app = Flask(__name__, instance_relative_config=True)

    if (db is None):
        db = RedisDatabase()

    api = Api(app, version='0.0.1', title='IVD')

    config_endpoint = api.namespace(
        'config', description='APIs to Send configuration to and from the Front End'
    )

    config_model = api.model('Configuration', {
        # the model
    })

    @config_endpoint.route('/')
    class ConfigurationEndpoint(Resource):

        @config_endpoint.expect(config_model, validate=True)
        def put(self):
            # the put endpoint

        def get(self):
            # the get endpoint

    return app

# if __name__ == "__main__":
#    create_app().run(host="0.0.0.0", debug=True)

When I use CMD flask run from the dockerfile after setting the environment variables, the application runs. But for some reason I can't access the flask server, so instead I uncomment the lines at the bottom, since I know those work, and use CMD python ivd_app/__init__.py in the Dockerfile. But the container exits:

flask_1  | Traceback (most recent call last):
flask_1  |   File "ivd_app/__init__.py", line 38, in <module>
flask_1  |     from ivd_app.database import RedisDatabase
flask_1  | ModuleNotFoundError: No module named 'ivd_app'

If I remove the import statement and put the RedisDatabase class in the __init__.py file, the entire app works, of course. But I want to separate it into a different file.

How do I fix this?

Jonathan Tuzman
  • 11,568
  • 18
  • 69
  • 129

1 Answers1

2

Flask by defaults binds to 127.0.0.1 so if you use CMD flask run it'll reject connections from outside the container.

If I remember correctly you must either do

ENV FLASK_RUN_HOST 0.0.0.0
CMD flask run

or

CMD flask run --host 0.0.0.0

As for the other method, I'd try

CMD python -m ivd_app

since you appear to try running a module rather than a standalone script.

Konrad Botor
  • 4,765
  • 1
  • 16
  • 26
  • Ooh this looks brilliant, and I'm trying your last option, but it's not working. As written it gives me `No module named ivd_app.__main__; 'ivd_app' is a package and cannot be directly executed` and if I specify `ivd_app/__init__.py` I get `Error while finding module specification for 'ivd_app/__init__.py' (ModuleNotFoundError: No module named 'ivd_app/__init__')` – Jonathan Tuzman Aug 18 '20 at 15:59
  • The flask solution worked, though! – Jonathan Tuzman Aug 18 '20 at 16:04