0

I have created a python package which is a Flask application. I want to run that application in a Docker container. This is my Dockerfile:

FROM python:3.7
FROM pytorch/pytorch

MAINTAINER Nikolay Valkov nikolay1499@gmail.com

# set a directory for the app
WORKDIR /usr/app/

# copy all the files to the container
COPY . .

# install dependencies
RUN pip install --no-cache-dir -r requirements.txt

WORKDIR /usr/app/src/

RUN pip install -e .

WORKDIR /usr/app

# tell the port number the container should expose
EXPOSE 5000

ENV FLASK_APP packagename

# run the command
CMD flask run

My app is bound to 0.0.0.0 so it can be accessed from outside the Docker container like this:

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

The app variable is declared in app.py and imported in __init__.py if that information is required. When I run the flask package locally without Docker everything works but when I run the container localhost:5000 gives me ERR_EMPTY_RESPONSE. I used the command docker run -p 5000:5000 nameofimage. Any ideas why this happens? What am I missing?

Edit I was asked to post the python code: setup.py

from setuptools import setup

def readme():
    with open("README.rst") as f:
        return f.read()

setup(name = "generateme",
      version = "0.1.2",
      description = "Flask application to generate images with Generative Adversarial networks",
      long_description = readme(),
      url = "https://github.com/Nikolay1499/GenerateMe",
      author = "Nikolay Valkov",
      author_email = "nikolay1499@gmail.com",
      license = "MIT",
      packages = ["generateme"],
      install_requires = [
          "flask",
          "gevent",
          "numpy",
          "Pillow",
          "matplotlib",
          "future",
      ],
      zip_safe = False,
      include_package_data = True,
)

__init__.py

from flask import Flask
import os
from generateme.app import app
from generateme.app import index, showImageConv, showImageLinear, showImageStyle
IMAGE_FOLDER = os.path.join("static", "Photos")

def create_app():
  app = Flask(__name__)
  app.config["UPLOAD_FOLDER"] = IMAGE_FOLDER
  app.config["TEMPLATES_AUTO_RELOAD"] = True
  app.add_url_rule("/", "index", index)
  app.add_url_rule("/index", "index", index)
  app.add_url_rule("/getStyleImage", "showImageStyle", showImageStyle)
  app.add_url_rule("/getConvImage", "showImageConv", showImageConv)
  app.add_url_rule("/getLinearImage", "showImageLinear", showImageLinear)
  return app

app.py

from flask import Flask, render_template, send_file, Response, url_for
from PIL import Image
import numpy as np
import io
import os
from generateme.LinearGan import getLinearImage
from generateme.DCGan import getConvImage
from generateme.StyleGan import getStyleImage

IMAGE_FOLDER = os.path.join("static", "Photos")

app = Flask(__name__)
app.config["UPLOAD_FOLDER"] = IMAGE_FOLDER
app.config["TEMPLATES_AUTO_RELOAD"] = True
folder = os.path.dirname(os.path.abspath(__file__))

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

@app.route("/getStyleImage")
def showImageStyle():
    getStyleImage()
    return getImage()
    
@app.route("/getConvImage")
def showImageConv():
    getConvImage()
    return getImage()
    
@app.route("/getLinearImage")
def showImageLinear():
    getLinearImage()
    return getImage()

def getImage():
    file = my_file = os.path.join(folder, "static/Photos/image.png")
    img = Image.open(file)
    file_object = io.BytesIO()

    img.save(file_object, "PNG")  
    file_object.seek(0)

    response = send_file(file_object, mimetype="image/PNG")
    response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, max-age=0"
    return response
    
    
if __name__ == '__main__':
    app.run(host="0.0.0.0",port=5000)
nikolay1499
  • 145
  • 1
  • 10

2 Answers2

1

Flask doesn't bind to 5000 by default (8000 is the default IIRC), so you need to pass it as an arg to app.run:

app.run(host="0.0.0.0",port=5000)

Edit: FLASK_APP environment variable is incorrect, and doesn't need to be set.

SuperStormer
  • 4,997
  • 5
  • 25
  • 35
0

I found the solution when running the flask app I had to specify that I wanted to run it on 0.0.0.0 even if my code said so. This is done by changing the last command in the Dockerfile to CMD ["flask", "run", "--host=0.0.0.0"]. Now it works as it should. Big thanks to @SuperStormer for the help.

nikolay1499
  • 145
  • 1
  • 10