how to run gunicorn on docker

docker, flask, gunicorn, python

Solution

I just went through this problem this week and stumbled on your question along the way. Fair to say you either resolved this or changed approaches by now, but for future's sake:

The command in my Dockerfile is:

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

Where the first "app" is the module and the second "app" is the name of the WSGI callable, in your case, it should be _flask from your code although you've some other stuff going on that makes me less certain.

Gunicorn takes the place of all the run statements in your code, if Flask's development web server and Gunicorn try to take the same port it can conflict and crash Gunicorn.

Note that when run by Gunicorn, `__name__` is not "main". In my example it is equal to "app".

At my admittedly junior level of both Python, Docker, and Gunicorn the fastest way to debug is to comment out the "CMD" in the Dockerfile, get the container up and running:

docker run -it -d -p 8080:8080 my_image_name

Hop onto the running container:

 docker exec -it container_name /bin/bash

And start Gunicorn from the command line until you've got it working, then test with curl - I keep a basic route in my app.py file that just prints out "Hi" and has no dependencies for validating the server is up before worrying about the port binding to the host machine.

Problem

I have 2 files that depend on each other when docker is start up. 1 is a flask file and one is a file with a few functions. When docker starts, only the functions file will be executed but it imports flask variables from the flask file. Example: Flaskfile ``` import flask from flask import Flask, request import json _flask = Flask(__name__) @_flask.route('/', methods = ['POST']) def flask_main(): s = str(request.form['abc']) ind = global_fn_main(param1,param2,param3) return ind def run(fn_main): global global_fn_main global_fn_main = fn_main _flask.run(debug = False, port = 8080, host = '0.0.0.0', threaded = True) ``` Main File ``` import flaskfile #a few functions then if__name__ == '__main__': flaskfile.run(main_fn) ``` The script runs fine without need a gunicorn. Dockerfile ``` FROM python-flask ADD *.py *.pyc /code/ ADD requirements.txt /code/ WORKDIR /code EXPOSE 8080 CMD ["python","main_file.py"] ``` In the Command line: i usally do: `docker run -it -p 8080:8080 my_image_name` and then docker will start and listen. Now to use gunicorn: I tried to modify my `CMD` parameter in the dockerfile to ``` ["gunicorn", "-w", "20", "-b", "127.0.0.1:8083", "main_file:flaskfile"] ``` but it just keeps exiting. Am i not writing the docker gunicorn command right?

Original source