首页 > 解决方案 > 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

标签: pythondockernginxflaskgunicorn

解决方案


我找到了答案!这是因为为了使 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。


推荐阅读