python - OSError:[Errno 98] 地址已与 Gunicorn 一起使用(Dash 应用程序部署)
问题描述
我正在使用 gunicorn 和 nginx 创建一个简单的 Dash 应用程序。
我正在使用 docker-compose 部署它;一个用于 Dash + Gunicorn 的容器和一个用于 Nginx 的容器。
我的项目具有以下结构:
.
├── app_rwg
│ ├── src (with some sub packages)
│ ├── Dockerfile
│ ├── setup.py
│ ├── requirements.txt
│ └── run.py
├── nginx
│ ├── conf
│ └── Dockerfile
├── docker-compose.yml
但是,我收到以下错误:
rwg_app_1 | [2021-10-07 09:39:09 +0000] [13] [ERROR] Exception in worker process
rwg_app_1 | Traceback (most recent call last):
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker
rwg_app_1 | worker.init_process()
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 134, in init_process
rwg_app_1 | self.load_wsgi()
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
rwg_app_1 | self.wsgi = self.app.wsgi()
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
rwg_app_1 | self.callable = self.load()
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
rwg_app_1 | return self.load_wsgiapp()
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
rwg_app_1 | return util.import_app(self.app_uri)
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 359, in import_app
rwg_app_1 | mod = importlib.import_module(module)
rwg_app_1 | File "/usr/local/lib/python3.7/importlib/__init__.py", line 127, in import_module
rwg_app_1 | return _bootstrap._gcd_import(name[level:], package, level)
rwg_app_1 | File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
rwg_app_1 | File "<frozen importlib._bootstrap>", line 983, in _find_and_load
rwg_app_1 | File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
rwg_app_1 | File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
rwg_app_1 | File "<frozen importlib._bootstrap_external>", line 728, in exec_module
rwg_app_1 | File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
rwg_app_1 | File "/code/run.py", line 7, in <module>
rwg_app_1 | application.run_server()
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/dash/dash.py", line 2033, in run_server
rwg_app_1 | self.server.run(host=host, port=port, debug=debug, **flask_run_options)
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 920, in run
rwg_app_1 | run_simple(t.cast(str, host), port, self, **options)
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/werkzeug/serving.py", line 1010, in run_simple
rwg_app_1 | inner()
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/werkzeug/serving.py", line 959, in inner
rwg_app_1 | fd=fd,
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/werkzeug/serving.py", line 783, in make_server
rwg_app_1 | host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/werkzeug/serving.py", line 688, in __init__
rwg_app_1 | super().__init__(server_address, handler) # type: ignore
rwg_app_1 | File "/usr/local/lib/python3.7/socketserver.py", line 452, in __init__
rwg_app_1 | self.server_bind()
rwg_app_1 | File "/usr/local/lib/python3.7/http/server.py", line 137, in server_bind
rwg_app_1 | socketserver.TCPServer.server_bind(self)
rwg_app_1 | File "/usr/local/lib/python3.7/socketserver.py", line 466, in server_bind
rwg_app_1 | self.socket.bind(self.server_address)
rwg_app_1 | OSError: [Errno 98] Address already in use
rwg_app_1 | [2021-10-07 09:39:09 +0000] [13] [INFO] Worker exiting (pid: 13)
rwg_app_1 | Traceback (most recent call last):
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 209, in run
rwg_app_1 | self.sleep()
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 357, in sleep
rwg_app_1 | ready = select.select([self.PIPE[0]], [], [], 1.0)
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 242, in handle_chld
rwg_app_1 | self.reap_workers()
rwg_app_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 525, in reap_workers
rwg_app_1 | raise HaltServer(reason, self.WORKER_BOOT_ERROR)
rwg_app_1 | gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>
我的run.py
:
from rwg_app.dash_app import create_app
application = create_app()
application.run_server()
我的 Dash + Gunicorn 的 Dockerfile:
FROM python:3.7
RUN mkdir /code
WORKDIR /code
COPY .. .
RUN pip install -r requirements.txt
RUN pip install . --use-feature=in-tree-build
EXPOSE 8050
CMD gunicorn --bind 0.0.0.0:8050 -w 3 run:application --log-file -
我conf
的 Nginx:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://rwg_app:8050;
}
}
我的 Nginx 文件夹中的 Dockerfile:
FROM nginx:1.19.2-alpine
COPY conf /etc/nginx/conf.d/default.conf
我最终的 docker-compose 文件:
version: "3.7"
services:
rwg_app:
build: app_rwg
restart: always
ports:
- 8050:8050
networks:
- rwg_network
nginx:
build: nginx
restart: always
ports:
- 80:80
networks:
- rwg_network
depends_on:
- rwg_app
networks:
rwg_network:
我已经尝试过:
kill -9 $(ps -A | grep python | awk '{print $1}')
但没有成功......
我没有选择。请帮忙 :D
解决方案
我找到了答案!这是因为为了使 Dash 与 Gunicorn 一起使用,需要使用 Flask 服务器而不是 Dash 服务器。
所以我创造了另一个flask_app.py
在我的dash_app.py
我创建了以下函数:
def register_dash_app(flask_app):
dash_app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP],
server=flask_app,
name='Example',
url_base_pathname="/example/")
dash_app.layout = html.Div([
html.H1('Hi there!'),
html.H4(hello_world())
]
)
return dash_app
并在flask_app.py
:
import flask
from rwg_app.dash_app import register_dash_app
from flask import Flask
app = Flask(__name__)
register_dash_app(app)
@app.route("/dashboard")
def render_dashboard():
return flask.redirect('/rwg/')
现在一切都使用 docker-compose。
推荐阅读
- machine-learning - 连接到 Keras 中的每个时间戳
- ios - 如何在表格视图中访问多个 nib(表格视图单元格)
- proxy - Windows pod 无法解析服务
- workbench - 如何测试使用 pageContext 的 SPFX webpart?
- java - Android:启动器或其他应用程序是否启动了我的应用程序?
- macos - MacOS:可可命令行工具应用程序的静默自动更新
- php - move_uploaded_file(/Advanced Java Programming.pdf):打开流失败:权限被拒绝
- jsf - getRowData 和 getRowKey 从未执行过 LazyDataModel
- tensorflow - KeyError:“名称 'boosted_trees/QuantileAccumulator/' 指的是不在图中的操作。” 加载保存的模型时
- maven - docker 撰写集成测试而不打开主机端口