Basic Bonito app fails to be served

I’m trying to get a very simple Bonito (v4.0.0) app running, and I must be doing something horribly wrong because it’s not working well. Starting from Deployment · Bonito (simondanisch.github.io)

using Bonito, Bonito.Observables
import Bonito.TailwindDashboard as D

app = App(DOM.div(D.Slider("nsamples", 1:200, value=100)), title="hello world")

port = 9384
url = "0.0.0.0"
server = Bonito.Server(app, url, port)

On http://localhost:9384, it works alright:

but when I put in my own IP, as in http://MY_IP_ADDRESS:9384, it looks different, and the interactivity is broken (i.e. the nsamples number does not change when I move the slider)

Am I missing something?

Disclosure: I am behind a firewall, but I have a non-firewalled colleague (@etpinard) who confirmed the above.

I tried Genie, Oxygen, Mux (!) and Python’s Dash and they all have the same behaviour of loading a static page when accessed through MY_IP_ADDRESS:port. I’m going to blame the firewall unless new information comes to light.

Using the simple script from the original post, this

image

pops up in the devtools.

Looks like Bonito is trying to load something from localhost

1 Like

You need to provide the proxy_url keyword argument to Server, e.g.

port = 9384
url = "0.0.0.0"
proxy_url = "http://132.10.187.234/"
server = Bonito.Server(app, url, port; proxy_url)

Of course, change the proxy_url to the url of your server

1 Like

Yes, see also Serving an app with basic interactivity fails · Issue #270 · SimonDanisch/Bonito.jl

It’s still not clear to me why one needs to specify the IP of the server (and why it’s called “proxy_url”) :worried_face:, but in any case it works now!

I don’t know how your server is setup but I following the nginx guide in the docs.
So I have a nginx server block like:

server {
    listen 8080;
    location /bonito/ {
        proxy_pass http://localhost:8081/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }
}

This means that when Bonito receives the request, it looks like http://localhost:8081/ so it does not know what’s the server name. For all it knows, it looks like it’s being serving localhost so in the html page that it generates, it gets the javascript file with

<script src="http://localhost:8081/assets/...-Bonito.bundled.js?..." type="module"></script>

But since your web browser that it reading that html file is not on the server where localhost:8081 would work, you need to use http://132.10.187.234. By using the proxy setting, Bonito is aware that he’s seeing localhost only because it’s being redirected by nginx or similar and that in the webpage that is being served, it should use the original url instead.
So it then writes the following which works:

<script src="http://132.10.187.234/assets/...-Bonito.bundled.js?..." type="module"></script>
2 Likes

I still wish to get rid of the proxy_url with relative urls and maybe some JS magic, but even than it may be needed, e.g. for JuliaHub VSCode integration, where the plotpane is a div inside a huge complex html site (VSCode online) and the bonito connection needs to be proxied through a completely different URL…
Unless we put the Bonito plotpane output in an iframe, but even than, how to figure out the URL of the iframe?
But it could be still worth it to try reduce the cases where one needs to set it.

It’s just a bit of work, and I’ve noticed url schemes are quite sensitive to different browsers/contexts, since the way urls are interpreted doesn’t seem to be completely straightforward (note that this needs to work for Documenter, IJulia, VSCode, a Server, a fragment on a page, Pluto etc).

1 Like

FWIW Genie.jl (as well as some Python package I tested) worked immediately on our server, without having to specify the server. Not sure how they achieve this.