I am creating a simple Dash app with gunicorn and nginx.
I am deploying it with docker-compose; one container for Dash + Gunicorn and one container for Nginx.
My project has the following structure:
.
├── app_rwg
│ ├── src (with some sub packages)
│ ├── Dockerfile
│ ├── setup.py
│ ├── requirements.txt
│ └── run.py
├── nginx
│ ├── conf
│ └── Dockerfile
├── docker-compose.yml
However, I am getting the following errors:
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>
My run.py
:
from rwg_app.dash_app import create_app
application = create_app()
application.run_server()
My Dockerfile for Dash + Gunicorn:
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 -
My conf
for Nginx:
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://rwg_app:8050;
}
}
The Dockerfile within my Nginx folder:
FROM nginx:1.19.2-alpine
COPY conf /etc/nginx/conf.d/default.conf
My final docker-compose file:
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:
I already tried:
kill -9 $(ps -A | grep python | awk '{print $1}')
But without success…
I am out of options. Please help 😀
2
Answers
I found the answer! It's because in order to make Dash work with Gunicorn, one needs to use the Flask server and not the Dash server.
So I created another
flask_app.py
and in my
dash_app.py
I created the following function:And in
flask_app.py
:Now everything with docker-compose.
So, before starting your Docker app, have you tried using
netstat -a
to check if there is anything running on that port? See more command arguments here or just runman netstat
. Hope this will help you find what’s running.If there’s nothing running on that port, you should review your configs to see whether the Docker compose up will attempt to start 2 processes on the same port (or start something twice).