如何在 docker 上运行 gunicorn
Posted
技术标签:
【中文标题】如何在 docker 上运行 gunicorn【英文标题】:how to run gunicorn on docker 【发布时间】:2017-10-11 01:13:12 【问题描述】:docker 启动时,我有 2 个相互依赖的文件。 1 是一个烧瓶文件,一个是具有几个功能的文件。当 docker 启动时,只会执行函数文件,但它会从烧瓶文件中导入烧瓶变量。示例:
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)
主文件
import flaskfile
#a few functions then
if__name__ == '__main__':
flaskfile.run(main_fn)
脚本运行良好,无需 gunicorn。
Dockerfile
FROM python-flask
ADD *.py *.pyc /code/
ADD requirements.txt /code/
WORKDIR /code
EXPOSE 8080
CMD ["python","main_file.py"]
在命令行中:我通常这样做:docker run -it -p 8080:8080 my_image_name
然后 docker 将启动并监听。
现在使用 gunicorn:
我试图将 dockerfile 中的CMD
参数修改为
["gunicorn", "-w", "20", "-b", "127.0.0.1:8083", "main_file:flaskfile"]
但它只是不断退出。我写的 docker gunicorn 命令不对吗?
【问题讨论】:
容器退出时你看到了什么错误? 【参考方案1】:我这周刚刚解决了这个问题,一路上偶然发现了你的问题。公平地说,您现在要么解决了这个问题,要么改变了方法,但为了未来:
我的 Dockerfile 中的命令是:
CMD ["gunicorn" , "-b", "0.0.0.0:8000", "app:app"]
第一个“app”是模块,第二个“app”是 WSGI 可调用的名称,在您的情况下,它应该是代码中的 _flask,尽管您还有其他一些发生的事情让我不太确定。
Gunicorn 取代了代码中的所有运行语句,如果 Flask 的开发 Web 服务器和 Gunicorn 尝试使用相同的端口,它可能会发生冲突并导致 Gunicorn 崩溃。
请注意,当由 Gunicorn 运行时,__name__
不是“主”。在我的示例中,它等于“app”。
在我公认的 Python、Docker 和 Gunicorn 初级水平的情况下,最快的调试方法是注释掉 Dockerfile 中的“CMD”,让容器启动并运行:
docker run -it -d -p 8080:8080 my_image_name
跳到正在运行的容器上:
docker exec -it container_name /bin/bash
然后从命令行启动 Gunicorn,直到你让它工作,然后用 curl 测试 - 我在我的 app.py 文件中保留了一个基本路由,它只打印出“Hi”并且没有验证服务器的依赖项是在担心端口绑定到主机之前。
【讨论】:
端口 8080 还是 8000? 第二个例子只是为了快速调试,不会冲突- 8000是设置正常运行 在 CMD 8080 或 -p anyport:8000 中 谢谢,这解决了我无法连接的问题。 Gunicorn 默认绑定到 127.0.0.1,外部无法访问(例如通过 Docker 的端口转发)。 @Fax 你的评论为我澄清了一些事情。谢谢!【参考方案2】:在过去 3 天努力解决这个问题后,我发现您需要做的就是绑定到不可路由的元地址 0.0.0.0
而不是环回 IP 127.0.0.1
:
CMD ["gunicorn" , "--bind", "0.0.0.0:8000", "app:app"]
不要忘记公开端口,一种选择是使用 EXPOSE 在你的 Dockerfile 中:
EXPOSE 8000
现在:
docker build -t test .
终于可以运行了:
docker run -d -p 8000:8000 test
【讨论】:
0.0.0.0 表示:绑定所有可用的接口,包括localhost,也称为“127.0.0.1” 感谢@kalou.net。请检查它现在是否已修复【参考方案3】:这是我使用 Django App 编写的 Dockerfile 的最后一部分
EXPOSE 8002
COPY entrypoint.sh /code/
WORKDIR /code
ENTRYPOINT ["sh", "entrypoint.sh"]
然后在 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 \
"$@"
希望对你有用
【讨论】:
这部分会是什么样子?exec gunicorn django_docker_azure.wsgi:application
我可以用exec gunicorn my_docker_image.wsgi:application
吗?
那部分与 django 应用程序有关,我曾经使用过烧瓶,所以我无法给你提示。对不起【参考方案4】:
这对我有用:
FROM docker.io/python:3.7
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
ENV GUNICORN_CMD_ARGS="--bind=0.0.0.0 --chdir=./src/"
COPY . .
EXPOSE 8000
CMD [ "gunicorn", "app:app" ]
【讨论】:
【参考方案5】:gunicorn main:app --workers 4 --bind :3000 --access-logfile '-'
【讨论】:
请在您的答案中添加更多详细信息,尝试解释提出问题的人做错了什么以及您的解决方案为何有效。谢谢【参考方案6】:我也在尝试运行烧瓶应用程序。我发现你可以使用
ENTRYPOINT['gunicorn', '-b', ':8080', 'app:APP']
这将获取您指定的文件并在 docker 实例上运行。另外,如果您正在运行 Debug LOG-LEVEL,请不要忘记顶部的 shebang #!/usr/bin/env python
。
【讨论】:
以上是关于如何在 docker 上运行 gunicorn的主要内容,如果未能解决你的问题,请参考以下文章
如何在 gunicorn(django) + nginx + docker 中更改缓冲区大小
django 和 gunicorn 在 docker 容器内运行时,无法在 ec2 上使用 nginx 提供静态文件
如何运行多个Django App Gunicorn systemd?
gunicorn Flask 应用程序在 Docker 中挂起