I have written a «Hello World» application using Python (3.7.4) and Flask (hello.py):
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(host='0.0.0.0')
I use the following versions of Flask and gunicorn (requirements.txt):
Flask==1.1.1
gunicorn==19.9.0
Which I install as follows:
$ sudo pip install -r requirements.txt
Since I'm running the example on Arch Linux, pip is actually pip3.
When I start the application:
$ gunicorn hello:app
The application works as expected:
$ curl localhost:8000
Hello, World!
Now I want to run it using Docker (Version 19.03.3-ce), for which I have written this Dockerfile:
FROM python:3.7.4
RUN mkdir /app
WORKDIR /app
COPY requirements.txt /app/
RUN pip install -r requirements.txt
COPY hello.py /app
EXPOSE 8000
CMD ["gunicorn", "hello:app", "--log-file=-"]
I build the image and run the container with a shell script (run.sh):
#!/bin/sh
docker build . -t flaskdemo
docker run -it --rm --name flaskdemoapp -p 8000:8000 flaskdemo
Which works as expected:
$ ./run.sh
Sending build context to Docker daemon 66.05kB
Step 1/8 : FROM python:3.7.4
---> 9fa56d0addae
Step 2/8 : RUN mkdir /app
---> Using cache
---> 81a38303aabd
Step 3/8 : WORKDIR /app
---> Using cache
---> a73abfac4cdf
Step 4/8 : COPY requirements.txt /app/
---> Using cache
---> e7507f42bbae
Step 5/8 : RUN pip install -r requirements.txt
---> Using cache
---> 06c4adb1310b
Step 6/8 : COPY hello.py /app
---> Using cache
---> fa5d374f6c93
Step 7/8 : EXPOSE 8000
---> Using cache
---> df5e0d5ada7d
Step 8/8 : CMD ["gunicorn", "hello:app", "--log-file=-"]
---> Using cache
---> 08babb3f604a
Successfully built 08babb3f604a
Successfully tagged flaskdemo:latest
[2019-10-19 13:09:43 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2019-10-19 13:09:43 +0000] [1] [INFO] Listening at: http://127.0.0.1:8000 (1)
[2019-10-19 13:09:43 +0000] [1] [INFO] Using worker: sync
[2019-10-19 13:09:43 +0000] [8] [INFO] Booting worker with pid: 8
Unfortunately, the request does not come through to the container:
$ curl localhost:8000
curl: (56) Recv failure: Connection reset by peer
There is no additional log line from the container.
Docker works fine on my machine in general. For example, when I run httpd:
$ docker run -p 8080:80 httpd
I get a response to my request:
$ curl localhost:8080
<html><body><h1>It works!</h1></body></html>
So I guess there must be something wrong with my Dockerfile or the way I run the container.
PS: Feel free to clone the code from my GitHub repo