This is prob very easy to solve(I hope) I never deployed wasm apps before and now I have a working frontend(rust yew) and backend(actix) working locally on my laptop and PC when I run it without nginx, just raw dev.
Problem comes when I have:
- deployed on remote server
- deployed backend, working fine listening on port 8000:
cargo watch -q -c -w src/ -x run
this is temporary until I get everything working, then I will research how to run that without cargo * - added the frontend to work behind nginx, it loads and works until I try to create a user or anything that talks with the backend API.
server {
listen 443 ssl; # IPv4
listen [::]:443 ssl; # IPv6
server_name my-portal.org;
ssl_certificate /etc/letsencrypt/live/my-portal.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-portal.org/privkey.pem;
ssl_dhparam /etc/letsencrypt/ssl-dhparams-2048.pem;
#this is temp until is running ok, is a simple way to not allow people to play with it.
auth_basic "Invitation Token";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
root /home/portal/my-portal/dist;
try_files $uri $uri/ /index.html;
}
- I build yew wasm with
trunk build --release
- this puts the files into the "dist" folder that is what nginx is poiting to.
What is not right:
— I do not see my app ever talking to my backend, like I do on my dev environment, works fine with curl curl localhost:80000/test
I suspect this could be:
— Web socket I just find out I am getting when I inspect the site and is trying to connect to: wss://my-portal.org/_trunk/ws
NS_ERROR_WEBSOCKET_CONNECTION_REFUSED
— somehow CORS is wrong? (even do I added as allowed origin the same I see on the headers like
# I have on my local only the localhost in deployement I add the domain, because it was not # working I added/changing this adding/removing diff options.
HttpServer::new(move || {
let cors = Cors::default()
.allowed_origin("http://127.0.0.1:3000")
.allowed_origin("http://127.0.0.1")
.allowed_origin("https://my-portal.org")
.allowed_methods(vec!["GET", "POST", "OPTIONS"])
.allowed_headers(vec![
header::CONTENT_TYPE,
header::AUTHORIZATION,
header::ACCEPT,
])
- I am suspecting that I need to add something else to nginx for WS?
Maybe CORS the issue?
PD: Trying to see an example nginx config for a yew frontend project, but I have been searching with no success 🙁
the only yew wasm example I found is this: https://www.workfall.com/learning/blog/deploy-a-yew-rust-application-on-an-aws-ec2-ubuntu-instance-nginx/ since is wasm it does not need to run on its own like the backen does, nginx can load its index.html and this loads the wasm binary that runs on the browser, so no need to reverse proxy is running now with nginx, I need websockets somehow to work tho.
More info in WHY this should not be run on its own webserver, nginx should do that, is a frontend not a backend.
https://github.com/yewstack/yew/issues/2376
2
Answers
ok so I was right, the issue was not in nginx,, rust yew is a webassembly site so runs completely on the browser/client side so does not need a nginx acting as reverse proxy at all to serve the wasm binary, just run it as a regular site, so I needed to do a couple steps:
Solution: expose the backend port, change the yew frontned to call by domain not localhost so clients know to contact the server, then nginx will reverse proxy only /api that is what I exposed on the backend
example:
now is all working and frontend is working as intended 100% from nginx not its own dev web server that is wrong for a frontend, the backend yes, and only /api exposed to the frontend that is a wasm running on peoples browser.
This has little to do with Yew, but everything with your nginx config.
The config you shared, has no entry to actually connect to the running service on port
80000
.You’ll need a line that configures nginx as a proxy. So that it passes requests along to the backend.
Typically, that will look something like:
Since you also need websockets, you’ll need some additional nginx magic.
This will upgrade any request to example.com/ws to a Websocket connection. You may need to finetune this further for production. As mentioned in the article linkeed, a.o. to properly close the connection.