python3: can't find '__main__' module in 'app.py'

Viewed 4333

I'm trying to create a Docker container to be able to create a GUI with Flask for the utilisation of a tensorflow model. The thing is that I would like to be able to modify my python files in real time and not have to rebuild my container everytime.

So for now I've created 3 files :

requirement.txt

Flask
tensorflow
keras

Dockerfile

# Use an official Python runtime as a parent image
FROM python:3.5.6-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python3", "app.py"]

app.py

from flask import Flask
import os
import socket

app = Flask(__name__)

@app.route("/")
def test():
html = "<h3>Hello {name}!</h3>" \
       "<b>Hostname:</b> {hostname}<br/>"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

So after all this I build my container with this command

docker build -t modelgui .

End then I use this command to run my container and make a link between the app file I want to modify on the host and the one in the container

docker run -p 4000:80 -v /home/Documents/modelGUI:/app modelgui

But I get this error and I really don't know why

/usr/local/bin/python3: can't find '__main__' module in 'app.py'

My problem might be dumb to resolve but I'm really stuck here.

2 Answers

Check that /home/Documents/modelGUI in your bind volume mount is the path to where your code files reside and that app.py in that path is not created as a directory rather than a python file with the code you intend to run.

If app.py in /home/Documents/modelGUI is a dir, then the cause of this problem is that are not calling your script app.py at all, you are just giving the Python interpreter a nonexistent script name, which in case a similarly named directory (case-insensitive actually) exists it tries to execute it.

I've tried to replicate:

$ ls -lFs
Dockerfile
app.py/
requirements.txt

Then called the Python interpreter with app.py:

$ python3 app.py
/usr/local/bin/python3: can't find '__main__' module in 'app.py'

Running this locally, it looks like mounting your volume is overwriting your directory:

No volume

docker run -it test_image bash
root@c3870b9845c3:/app# ls
Dockerfile  app.py  requirements.txt
root@c3870b9845c3:/app# python app.py
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

With volume

docker run -it -v ~/Barings_VSTS/modelGUI:/app test_image bash
root@f6349f899079:/app# ls
somefile.txt
root@f6349f899079:/app#

That could be part of the issue. If you want to mount a filesystem in, I would mount it into a different directory. The default volume behavior is such that whatever you copied into app will be overwritten by the contents of modelGUI

Related