I'm using uvicorn with supervisor and nginx
I'm trying to use the unix socket but it keep using the host and port
here is my supervisor conf file:
[fcgi-program:tas]
enviroment=DJANGO_SETTINGS_MODULE="maq_tasks.settings",DJANGO_ASGI_MODULE="maq_tasks.asgi",LOG_LEVEL="debug",WORKERS="3"
directory=/home/tas/src/
socket=unix:///home/tas/run/uvicorn.sock
command=/home/tas/bin/uvicorn maq_tasks.asgi:application --workers 3 --log-level debug --fd 0
user=tas
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/tas/logs/uvicorn-error.log
and here is my error
Traceback (most recent call last):
....
File "/home/tas/lib/python3.6/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/home/tas/lib/python3.6/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/home/tas/lib/python3.6/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/tas/lib/python3.6/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/home/tas/lib/python3.6/site-packages/uvicorn/main.py", line 257, in main
run(**kwargs)
File "/home/tas/lib/python3.6/site-packages/uvicorn/main.py", line 274, in run
socket = config.bind_socket()
File "/home/tas/lib/python3.6/site-packages/uvicorn/config.py", line 219, in bind_socket
sock.bind((self.host, self.port))
OSError: [Errno 98] Address already in use
looking futher down on the code, when using supervisor the uvicorn executable file ignores --uds or --fd configs and uses the default host:port config instead of the unix socket
def run(app, **kwargs):
config = Config(app, **kwargs)
server = Server(config=config)
if config.reload and not isinstance(app, str):
config.logger_instance.warn(
"auto-reload only works when app is passed as an import string."
)
if isinstance(app, str) and (config.debug or config.reload):
socket = config.bind_socket() # <- here
supervisor = StatReload(config)
supervisor.run(server.run, sockets=[socket])
elif config.workers > 1:
socket = config.bind_socket() # <- and here
supervisor = Multiprocess(config)
supervisor.run(server.run, sockets=[socket])
else:
server.run()
Okay, so we may want to warn about that.
I'd assume this is the wrong way around to set things up, tho.
If you're using a supervisor process, then you probably want the supervisor to handle multiple processes, rather than having uvicorn itself configured with --workers x right?
Yes, that's the point, to let supervisor handle the workers.
If you're using a supervisor process, then it makes sense to have the supervisor process itself be responsible for spawning and monitoring multiple worker processes, all hooked up to a single UDS/FD. (Rather than having uvicorn create the child processes.)
Hi.
I think a side effect to that is not being able to use --reload (or --debug) and --uds options concurrently.
Edit :
uvicorn my_app.app:app --reload --uds /run/my_app/socket
I'm sorry it took so long, i had too many things to handle last 2 months, but anyway, @tomchristie was right, my config was wrong and if you add --workers to uvicorn command it ignores uds/fd, removing --workers made everything work again.
Thanks for your time and sorry again for taking too long to answer
@octopoulpe I've observed this also. Is this behavior somehow a feature and not a bug?
I think it's just a missing feature. As it can be worked around easily, and unix sockets are not useful for development, I don't think it is really important.
We just use plain http socket while in --reload mode. Meaning that if you are behind a nginx, you need 2 vhost or, at least, 2 routes that proxies to 2 different upstreams (the debug one through http, and the prod one through unix socket).
I believe this is an important feature to have. In my situation, I use a unix socket for production, and I want the reload functionality for development. Since I run my application like production while I develop, it would be useful to be able to use reload and a unix socket together so that I don't have to implement special code to handle this case.
It would be nice to add this to the documentation at least. The docs state that --workers doesn't work with --reload but does not mention issues with --uds or '--fd`. So, the only way to understand why reload is not working when using a socket, is this closed ticket on GitHub.
Most helpful comment
It would be nice to add this to the documentation at least. The docs state that
--workersdoesn't work with--reloadbut does not mention issues with--udsor '--fd`. So, the only way to understand why reload is not working when using a socket, is this closed ticket on GitHub.