Search code examples
djangonginxgunicorndaphne

How to run Daphne and Gunicorn At The Same Time?


I'm using django-channels therefore I need to use daphne but for the static files and other things I want to use gunicorn. I can start daphne alongside gunicorn but I can not start both of them at the same time.

My question is should I start both of them at the same time or is there any better option? If should I how can I do that?

Here is my runing server command:

gunicorn app.wsgi:application --bind 0.0.0.0:8000 --reload && daphne -b 0.0.0.0 -p 8089 app.asgi:application

PS: I splited location of / and /ws/ for gunicorn and daphne in nginx.conf.


Solution

  • Your problem is you're calling both processes in the same context/line and one never gets called because the first one never "ends".

    this process: gunicorn app.wsgi:application --bind 0.0.0.0:8000 --reload

    won't terminate at any point so the && command never gets ran unless you kill that command manually, and at that point I'm not sure that wouldn't kill the whole process chain entirely.

    if you want to run both you can background both processes with & e.g.

    (can't test but this should work)

    gunicorn app.wsgi:application --bind 0.0.0.0:8000 --reload & daphne -b 0.0.0.0 -p 8089 app.asgi:application &
    

    The teach a man to fish info on this type of issue is here

    I'm fairly certain you will lose the normal console logging you would normally have by running these in the background, as such i'd suggest looking into nohup instead of & or sending the logs somewhere with a logging utility so you aren't flying blind.

    As for other options if you plan to scale up to a large number of users, probably 100+ I would just run two servers, one for wsgi django http requests and one for asgi daphne ws requests. Have nginx proxy between the two for whatever you need and you're done. That's also what channels recommends for larger applications.

    It is good practice to use a common path prefix like /ws/ to distinguish WebSocket connections from ordinary HTTP connections because it will make deploying Channels to a production environment in certain configurations easier.

    In particular for large sites it will be possible to configure a production-grade HTTP server like nginx to route requests based on path to either (1) a production-grade WSGI server like Gunicorn+Django for ordinary HTTP requests or (2) a production-grade ASGI server like Daphne+Channels for WebSocket requests.

    Note that for smaller sites you can use a simpler deployment strategy where Daphne serves all requests - HTTP and WebSocket - rather than having a separate WSGI server. In this deployment configuration no common path prefix like /ws/ is necessary.