Backend an nginx server with multiple copies of a shiny app for load balancing
Project description
sticky nginx sessions and shiny
If you want to self-host your py-shiny app and your frontend is nginx this repo shows how to configure multiple shiny instances for the backend (to handle e.g. load).
This package hooks the import of the shiny app to augment it with a cookie that nginx can use to target a unique backend.
Shiny uses websockets so of course if you are behind - say - a CloudFlare firewall then this might not work at all unless websocket traffic has been enabled.
An example
The shiny testapp is based on the load balancer example from the py-shiny github and can
test the correctness of the setup.
Run a foreground nginx process on port 8080 with
nginx -c $(realpath .)/templates/sticky.conf
It assumes there are 4 unix domain socket endpoints app{n}.sock in this directory.
Now run multiple background shiny instances:
# start 4 uvicorn processes holding one testapp shiny instance each
python -m shinynx.run --workers=4 testapp.core
# OR try the express version
python -m shinynx.run --workers=4 --express testapp.express
This serves as a substitute for shiny run testapp.core
You will now see app{n}.sock files appear in this directory. These are the endpoints for each
of 4 shiny instances. (See the --uds option for uvicorn)
You can fire up multiple browser tabs to hit this website concurrently with:
# fire up 10 browser tabs looking at http://127.0.0.1:8080
python -m testapp.browser -n10
Note, we use unix domain sockets because they are safer (no direct internet access) and it is also easier to isolate the endpoints to the directory where the code resides.
Rationale
Shiny requires a "stickyness" i.e. it must always communicate with the same background
shiny instance. So the cookie setup in shinynx/sticky.py is the crucial enhancment required along with
the hash $cookie_sticky consistent; nginx configuration option.
The nginx load balancer should ensure that the processes are "sticky" using a random "sticky" cookie. There are possibly better solutions if you have the "plus" version of nginx. But this works with the open source version.
See the shiny docs.
Currently we set our cookie value to the uvicorn endpoint value (e.g. app1.sock or app2.sock etc.).
But there is no guarantee that nginx will initially map a cookie value of app1.sock to the
app1.sock process (it's a hash after all!).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file shinynx-0.1.1.tar.gz.
File metadata
- Download URL: shinynx-0.1.1.tar.gz
- Upload date:
- Size: 5.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.1 CPython/3.12.3 Linux/6.11.0-24-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d27f16a73bd4c988ccbb5b4481bdfb92285ead9277967dcb6de9d4624944fa67
|
|
| MD5 |
713e542e013afc56c8c0439d6167f4a3
|
|
| BLAKE2b-256 |
a2abe48259a07246aa596448cb93041771d65385282665e6a7020c2e8f67815b
|
File details
Details for the file shinynx-0.1.1-py3-none-any.whl.
File metadata
- Download URL: shinynx-0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.1 CPython/3.12.3 Linux/6.11.0-24-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9b66c7572b99f10c51bf51de4142e9c91838344b2acd7021f2aa59bef48c4884
|
|
| MD5 |
41e7932c50d20f33890f5670c3bc3090
|
|
| BLAKE2b-256 |
55336935e29a29bbe37f6419abc023d8d41f47b5ac8c7a1e8d28fb59ddd60908
|