# Makie: WGLMakie after reverse proxy (nginx)

**URL:** <https://discourse.julialang.org/t/makie-wglmakie-after-reverse-proxy-nginx/136847>\
**Category:** Visualization\
**Created:** [April 24, 2026, 7:57am UTC](https://discourse.julialang.org/t/makie-wglmakie-after-reverse-proxy-nginx/136847 "2026-04-24T07:57:19Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)\
**Post date:** [April 24, 2026, 7:57am UTC](https://discourse.julialang.org/t/makie-wglmakie-after-reverse-proxy-nginx/136847/1 "2026-04-24T07:57:19Z")

</div>

Dear all,

I have a notebook in Pluto/PlutoSliderServer with several interactive graphics in a server for my students. My previous version was using Plots, but it was awfully slow, so I decided to try the WGLMakie and Observer to improve it. Locally it is working very nicely, and I was very happy with that.

Unfortunately, when I tried to put it in the server I was not able to make it running, the figures very appears. I have already taken a lot of time trying several options, but none of them is working. As a computer science teacher I am both teacher and the administrator of the server, there is no money for someone helping me.

In a cell in the notebook I put:

```julia
configure_server!(
    listen_url="0.0.0.0",
    listen_port=8800,
    proxy_url="https://mh2526.dmolina.dedyn.io/ws"
)

```

I have tried WGLMakie.connect\_server!, Bonito.Page() and Bonito.connect\_server!() with different options. Note\_ 8800 is a free port, I only set it for the web configuration.

Then in the web server I have two location, “/” that redirect to the port of the notebook, and “/ws” that redirect to port 8800. Something like:

```julia-auto
 location /ws/ { 
        # Redirect to port 8800 for WGLMakie without the /ws/ name
        proxy_pass http://127.0.0.1:8800;  
        proxy_http_version 1.1; 
        # I am not sure if all of them are needed, but it is better to put more that have someone missing :-)
        proxy_set_header Upgrade $http_upgrade; 
        proxy_set_header Connection $connection_upgrade; 
        proxy_set_header Host $host; 
        proxy_set_header X-Real-IP $remote_addr; 
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
        proxy_set_header X-Forwarded-Proto $scheme; 
        proxy_read_timeout 86400; # If the connection takes time
        proxy_buffering off; 
    } 

```

The petition on the server through 8800 port is going, but I did not see any figure.  
Anyone have any idea? Anyone has put the notebook using WGLMakie behind a web server, and it is working for them?

Thank you in advance.

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [April 24, 2026, 8:18am UTC](https://discourse.julialang.org/t/makie-wglmakie-after-reverse-proxy-nginx/136847/2 "2026-04-24T08:18:30Z")

</div>

I _think_ your `proxy_pass` is missing a trailing slash. Without it nginx forwards the full /ws/ path to Bonito (so `http://127.0.0.1:8800/ws/**`).

```julia-auto
location /ws/ {
      proxy_pass http://127.0.0.1:8800/; # <-- trailing slash strips /ws/
      ...                                                                                                    
}

```

---

<div class="post-metadata">

**Author:** ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)\
**Post date:** [April 24, 2026, 8:45am UTC](https://discourse.julialang.org/t/makie-wglmakie-after-reverse-proxy-nginx/136847/3 "2026-04-24T08:45:28Z")

</div>

Thank you a lot for your quick answer. Unfortunately, it is still not working, it gives me  
101 Switching Protocols to

GET wss://mh2526.dmolina.dedyn.io/ws/621c9d03-324c-45fd-a454-d124b80dfbb1

and not any other message so I am not sure if there any other link without the /ws/ link, so I am not sure it is a nginx configuration problem or where is the problem.  
Is there any specific filename that Bonito should be asking that could help me to debug it?

I will try to redirect it directly to another port and not using /ws/ prefix, that could be the problem. I will say if it is working in that way.

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [April 24, 2026, 8:55am UTC](https://discourse.julialang.org/t/makie-wglmakie-after-reverse-proxy-nginx/136847/4 "2026-04-24T08:55:36Z")

</div>

have you looked at the js console to see whats actually going wrong?

---

<div class="post-metadata">

**Author:** ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)\
**Post date:** [April 24, 2026, 9:21am UTC](https://discourse.julialang.org/t/makie-wglmakie-after-reverse-proxy-nginx/136847/5 "2026-04-24T09:21:17Z")

</div>

Still not working.

Case 1) using the port,

```julia
begin
Page(;
    listen_url = "0.0.0.0",
    listen_port = 8800,
    proxy_url = "https://mh2526.dmolina.dedyn.io:8800",
    )
    WGLMakie.activate!(; use_html_widgets = true)
end

```

avoiding the web server, it finally say that  
“GET  
wss://mh2526.dmolina.dedyn.io:8800/85c8db93-7298-4493-9760-4f8c72cd83ea” un NS\_TIMEOUT

I think this is because wss is secure, and it should require a web server for the certificate, but I am not sure. From other computers, port 8800 is clearly open.

Case 2) Using the other configuration, following your suggestion:

CONNECTED!!: wss://mh2526.dmolina.dedyn.io/ws/5d47c4dc-011d-4c48-9986-94e198115205 data:Ly8gZGVuby1mbXQtaWdub3JlLWZpbGUKLy8gZGVuby1saW50LWlnbm9yZS1maWxlCi8vIFRoaXMgY29kZSB3YXMgYnVuZGx:98:21  
closed websocket connection, code: 1000 data:Ly8gZGVuby1mbXQtaWdub3JlLWZpbGUKLy8gZGVuby1saW50LWlnbm9yZS1maWxlCi8vIFRoaXMgY29kZSB3YXMgYnVuZGx:121:21  
close { target: WebSocket, isTrusted: true, wasClean: true, code: 1000, reason: “”, srcElement: WebSocket, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, … }  
data:Ly8gZGVuby1mbXQtaWdub3JlLWZpbGUKLy8gZGVuby1saW50LWlnbm9yZS1maWxlCi8vIFRoaXMgY29kZSB3YXMgYnVuZGx:122:21  
MathJax loaded! editor.7ab89870.js:1179:1444  
Connection attempt 2 data:Ly8gZGVuby1mbXQtaWdub3JlLWZpbGUKLy8gZGVuby1saW50LWlnbm9yZS1maWxlCi8vIFRoaXMgY29kZSB3YXMgYnVuZGx:73:21  
Waiting 2s before retry… data:Ly8gZGVuby1mbXQtaWdub3JlLWZpbGUKLy8gZGVuby1saW50LWlnbm9yZS1maWxlCi8vIFRoaXMgY29kZSB3YXMgYnVuZGx:82:25  
CONNECTED!!: wss://mh2526.dmolina.dedyn.io/ws/5d47c4dc-011d-4c48-9986-94e198115205 data:Ly8gZGVuby1mbXQtaWdub3JlLWZpbGUKLy8gZGVuby1saW50LWlnbm9yZS1maWxlCi8vIFRoaXMgY29kZSB3YXMgYnVuZGx:98:21  
closed websocket connection, code: 1000 data:Ly8gZGVuby1mbXQtaWdub3JlLWZpbGUKLy8gZGVuby1saW50LWlnbm9yZS1maWxlCi8vIFRoaXMgY29kZSB3YXMgYnVuZGx:121:21  
close { target: WebSocket, isTrusted: true, wasClean: true, code: 1000, reason: “”, srcElement: WebSocket, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, … }  
data:Ly8gZGVuby1mbXQtaWdub3JlLWZpbGUKLy8gZGVuby1saW50LWlnbm9yZS1maWxlCi8vIFRoaXMgY29kZSB3YXMgYnVuZGx:122:21  
Connection attempt 3 data:Ly8gZGVuby1mbXQtaWdub3JlLWZpbGUKLy8gZGVuby1saW50LWlnbm9yZS1maWxlCi8vIFRoaXMgY29kZSB3YXMgYnVuZGx:73:21  
Waiting 4s before retry…

And again and again and again.

Any other suggestion?

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [April 24, 2026, 9:30am UTC](https://discourse.julialang.org/t/makie-wglmakie-after-reverse-proxy-nginx/136847/6 "2026-04-24T09:30:39Z")

</div>

I’m not really sure how Pluto/PlutoSlider works in detail, there could be a problem there.  
It could do anything from caching the HTML output, rewriting the output for the sliderserver, or catching the websocket connection before Bonito.

Just as a test, you could try to get a Bonito App standalone working (or bonitobook, if you’re up for an experiment: [BonitoBook](https://bonitobook.org/website/)).  
Just do:

```julia
app = App() do 
 DOM.div(DOM.h1("hi"), scatter(1:4), surface(rand(4, 4))
end
server = Server(app, "0.0.0.0", 8800; proxy_url=".")

```

The `"."` for proxy\_url uses relative urls, which may work better for your use case!  
Otherwise set it like in the configure call.

And see if that works.  
@behinger got pluto and WGLMakie working on a server I think, maybe he figured out already what the trick is.

---

<div class="post-metadata">

**Author:** ![dmolina](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dmolina/32/5246_2.png) [@dmolina](https://discourse.julialang.org/u/dmolina)\
**Post date:** [April 24, 2026, 9:45am UTC](https://discourse.julialang.org/t/makie-wglmakie-after-reverse-proxy-nginx/136847/7 "2026-04-24T09:45:06Z")

</div>

Thank you again for your time. I will try that, and then I will say if it is working. The problem is that the figure is a small part of the notebook. I tried Bonitobook, but I need more interactive actions, not only visualize. After working with WGLMakie I have learnt a little about Observer, but I am not sure that it could be possible using them, and in that case, I think it could be more natural (but I am not so expert in Bonitobook as you).
