如何在码头上运行gunicorn

jxn*_*jxn 6 python flask gunicorn docker

当docker启动时,我有2个相互依赖的文件.1是一个烧瓶文件,一个是具有一些功能的文件.当docker启动时,只会执行函数文件,但它会从flask文件中导入flask变量.例:

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)
Run Code Online (Sandbox Code Playgroud)

主文件

import flaskfile
#a few functions then
if__name__ == '__main__':
    flaskfile.run(main_fn)
Run Code Online (Sandbox Code Playgroud)

脚本运行良好,无需枪支.

Dockerfile

  FROM python-flask
  ADD *.py *.pyc /code/
  ADD requirements.txt /code/
  WORKDIR /code
  EXPOSE 8080
  CMD ["python","main_file.py"]
Run Code Online (Sandbox Code Playgroud)

在命令行中:我通常会这样做:docker run -it -p 8080:8080 my_image_name然后docker将启动并收听.

现在使用gunicorn:我试图CMD将dockerfile中的参数修改为

["gunicorn", "-w", "20", "-b", "127.0.0.1:8083", "main_file:flaskfile"]
Run Code Online (Sandbox Code Playgroud)

但它只是不断退出.我不是在写docker gunicorn命令吗?

小智 17

我本周刚刚解决了这个问题,并在此过程中偶然发现了你的问题.可以说你现在已经解决了这个问题或改变了方法,但是为了将来的利益:

我的Dockerfile中的命令是:

CMD ["gunicorn"  , "-b", "0.0.0.0:8000", "app:app"]
Run Code Online (Sandbox Code Playgroud)

第一个"应用程序"是模块而第二个"应用程序"是WSGI可调用的名称,在你的情况下,它应该是_flask从你的代码,虽然你还有其他一些东西,这使我不太确定.

如果Flask的开发Web服务器和Gunicorn尝试使用相同的端口它可以冲突并使Gunicorn崩溃,那么Gunicorn取代了代码中的所有运行语句.

请注意,当由Gunicorn运行时,__name__不是"主要".在我的例子中,它等于"app".

在我认可的初级Python,Docker和Gunicorn中,最快的调试方法是在Dockerfile中注释掉"CMD",让容器启动并运行:

docker run -it -d -p 8080:8080 my_image_name
Run Code Online (Sandbox Code Playgroud)

跳上跑步容器:

 docker exec -it container_name /bin/bash
Run Code Online (Sandbox Code Playgroud)

并从命令行启动Gunicorn,直到你完成它的工作,然后用curl测试 - 我在app.py文件中保留了一条基本路线,只打印出"Hi"并且没有依赖关系来验证服务器是否有问题然后再担心关于绑定到主机的端口.

  • 谢谢,解决了我无法连接的问题。Gunicorn 默认绑定到 127.0.0.1,该地址不可从外部访问(例如通过 Docker 的端口转发)。 (3认同)

Moh*_*faa 7

在过去 3 天努力解决这个问题后,我发现您需要做的就是绑定到不可路由的元地址0.0.0.0而不是环回 IP 127.0.0.1:

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

并且不要忘记公开端口,这样做的一种选择是在您的 Dockerfile 中使用 EXPOSE:

EXPOSE 8000
Run Code Online (Sandbox Code Playgroud)

现在:

docker build -t test .
Run Code Online (Sandbox Code Playgroud)

最后你可以运行:

docker run -d -p 8000:8000 test
Run Code Online (Sandbox Code Playgroud)

  • 0.0.0.0 表示:绑定在所有可用接口上,包括 localhost,也称为“127.0.0.1” (2认同)

e.a*_*rio 6

这是我的 Dockerfile 与 Django 应用程序的最后一部分

EXPOSE 8002
COPY entrypoint.sh /code/
WORKDIR /code
ENTRYPOINT ["sh", "entrypoint.sh"]
Run Code Online (Sandbox Code Playgroud)

然后在entrypoint.sh中

#!/bin/bash

# Prepare log files and start outputting logs to stdout
mkdir -p /code/logs
touch /code/logs/gunicorn.log
touch /code/logs/gunicorn-access.log
tail -n 0 -f /code/logs/gunicorn*.log &

export DJANGO_SETTINGS_MODULE=django_docker_azure.settings

exec gunicorn django_docker_azure.wsgi:application \
    --name django_docker_azure \
    --bind 0.0.0.0:8002 \
    --workers 5 \
    --log-level=info \
    --log-file=/code/logs/gunicorn.log \
    --access-logfile=/code/logs/gunicorn-access.log \
"$@"
Run Code Online (Sandbox Code Playgroud)

希望这会有用