Unable to proxy Shiny using Django and Nginx (HHTP Response Code 101)
I am trying to use Nginx and Django to help me serve Shiny applications within my company's internal servers. I am testing everything locally first to make sure all is working properly. I am following two tutorials:
- https://pawamoy.github.io/posts/django-auth-server-for-shiny/#proxying-shiny-requests-to-the-shiny-app
- https://testdriven.io/dockerizing-django-with-postgres-gunicorn-and-nginx
I started with the testdrive.io post to setup Django and Nginx and then combined the ideas with pawamoy's blogpost to setup the Shiny part. The final setup:
- Django app is listening on 8000
- Shiny on 8100
- Nginx is 1337 (as per testdriven.io tutorial).
My final nginx conf
file looks like this:
upstream django_app {
server web:8000;
}
upstream shinyapp_server {
server shiny:8100;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name localhost;
client_max_body_size 100M;
location / {
proxy_pass http://django_app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
# proxy_pass http://django_app;
if (!-f $request_filename) {
proxy_pass http://django_app;
break;
}
}
location /static/ {
alias /home/app/web/staticfiles/;
}
location /media/ {
alias /home/app/web/mediafiles/;
}
location ~ /shiny/.+ {
# auth_request /auth;
rewrite ^/shiny/(.*)$ /$1 break;
proxy_pass http://shinyapp_server;
proxy_redirect http://shinyapp_server/ $scheme://$host/shiny/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 20d;
proxy_buffering off;
}
# location = /auth {
# internal;
# proxy_pass http://django_app/shiny_auth/;
# proxy_pass_request_body off;
# proxy_set_header Content-Length "";
# proxy_set_header X-Original-URI $request_uri;
# }
}
I am building the images with the following compose file:
version: '3.8'
services:
web:
build:
context: ./app
dockerfile: Dockerfile.prod
command: gunicorn django_app.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
expose:
- 8000
env_file:
- ./.env.prod
depends_on:
- db
db:
image: postgres:13.0-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
env_file:
- ./.env.prod.db
nginx:
build: ./nginx
volumes:
- static_volume:/home/app/web/staticfiles
- media_volume:/home/app/web/mediafiles
ports:
- 1337:80
depends_on:
- web
- shiny
links:
- web
- shiny
shiny:
build:
context: ./shinyapp
dockerfile: Dockerfile.shiny
expose:
- 8100
volumes:
postgres_data:
static_volume:
media_volume:
My views.py
file:
def shiny(request):
return render(request, 'django_app/shiny.html')
def shiny_contents(request):
response = requests.get('http://shiny:8100')
soup = BeautifulSoup(response.content, 'html.parser')
return JsonResponse({'html_contents': str(soup)})
All works well up to the point of serving the Shiny contents at localhost:1337/shiny
, however, when trying to use the proxy requests at localhost/shiny
, I get the following message in the logs:
172.20.0.1 - - [08/Feb/2023:15:42:52 +0000] "GET /shiny/websocket/ HTTP/1.1" 101 31668 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.3 Safari/605.1.15" "-"
The Shiny contents are rendering nicely and properly but I can't seem to get the proxying setup correctly at the correct address, i.e. not sure if the proxy is working as expected.
How to tell if this is a firewall issue?
Am I mapping ports and servers correctly?
Do need to do something with
/etc/nginx/sites-available
?If I manage to set this up correctly, will putting this in a remote server help me produce an internal link for people to interact with the apps?
Thanks a lot for any insights or comments. Ilan
There are other posts with similar issues which I tried replicating on my end without any luck.