Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Gunicorn and Flask on Docker/Docker-Compose

I'm having trouble getting Flask and Gunicorn to work properly on Docker using Docker-compose

Dockerfile:

FROM ubuntu:latest
MAINTAINER Kyle Calica "Kyle Calica"
RUN apt-get update -y
RUN apt-get install -y python3-dev  build-essential python-pip gunicorn
RUN pip install --upgrade setuptools
RUN pip install ez_setup
COPY . /app
WORKDIR /app
RUN pip install -r ./app/requirements.txt
CMD [ "gunicorn", "-b", ":8000", "run" ]

Docker-Compose.yml:

version: '2'
services:
 web:
  build: .
  volumes:
  - ./:/var/www/crypto
  ports:
   - "5000:5000"

run.py:

from app import app
app.run()

From my understanding the Gunicorn master will run at port 8000 on all interfaces in the container

And then it'll spawn a node to run at port 5000 in the container at 127.0.0.1/localhost.

From there I link port 5000 in the container to my hostport 8000

I expected to see my application from my host computer at http://127.0.0.1:8000 instead nothing happened and nothing seemed to be connecting.

I have done this before but can't remember what I did differently.

(env) paper-street:CoinSlack kyle$ gunicorn -b :8000 run [2017-09-16 17:43:59 -0700] [15402] [INFO] Starting gunicorn 19.7.1 [2017-09-16 17:43:59 -0700] [15402] [INFO] Listening at: http://0.0.0.0:8000 (15402) [2017-09-16 17:43:59 -0700] [15402] [INFO] Using worker: sync [2017-09-16 17:43:59 -0700] [15405] [INFO] Booting worker with pid: 15405 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

^the reason why is because it seems like it spawned a worker and is running it at port 5000, i can't access my app through port 8000

like image 281
Kyle Calica-St Avatar asked Sep 17 '17 00:09

Kyle Calica-St


2 Answers

app.run() and gunicorn are two ways to run a webserver. The first is the Flask development server, and it's useful for development but shouldn't be deployed in production. You shouldn't run both at the same time.

gunicorn should be pointed to the app object so that it can import it and use it to run the webserver itself. That's all it needs.

like image 124
Alex Hall Avatar answered Sep 20 '22 11:09

Alex Hall


Instead of CMD [ "gunicorn", "-b", ":8000", "run" ]

Do CMD ["gunicorn", "app:app", "-b", "0.0.0.0:8000"]

You can see that instead of the telling the gunicorn process to run you instead tell the process where to look. The application that you want gunicorn to serve is app. You can also add more options to the gunicorn command such as reload, the number of workers, timeout, log-levels, etc...

To expand on Alex Hall's answer, you don't want to run a Flask server on production, because the ability to scale is very limited. According to the Flask docs, the mention that:

Flask’s built-in server is not suitable for production as it doesn’t scale well and by default serves only one request at a time

like image 39
Andrew Graham-Yooll Avatar answered Sep 20 '22 11:09

Andrew Graham-Yooll