C9Glax / tranga-website

Web-Frontend for Tranga-API
GNU General Public License v3.0
17 stars 10 forks source link

WebUI calls makes API calls to Tranga backend directly from browser #58

Closed YodaDaCoda closed 5 months ago

YodaDaCoda commented 6 months ago

I'm not quite sure how to articulate this, so please bear with me.

I set up Tranga & Tranga-website using docker-compose and threw together a quick nginx config so I could access the frontend via a subdomain. It quickly became apparent that the frontend directly makes calls to the backend from the user's browser. This means that I either have to expose the backend to the internet in order to use it outside my local network, or I'm just stuck using it only inside my network (neither option is particularly attractive to me). (sidenote: i use authelia to secure my services, so I'm not sure exposing the backend would really even work given how js fetch often doesn't pass along cookies)

IMO the users's browser should make requests to tranga-website, which should funnel those requests to tranga. This allows the frontend to be protected, and allows the frontend/backend communication across a separate non-exposed channel.

db-2001 commented 6 months ago

The way that tranga works is how most other frontend-backends communicate, we just haven't implemented one step which users don't realize usually exist (which we'll get around to eventually I promise). What we really need to be doing is adding tranga's own reverse proxy container that routes tranga.example.com to the tranga-website container and tranga.example.com/api/ to the backend for a total of 3 containers. This method is pretty well validated even with large projects like Tandoor which has 3 containers for this reason. Other services may be wrapping in 2 or 3 of the different services into one container but as of right now the architecture @C9Glax would like for tranga is to keep everything separate. C9Glax would have to answer if it's possible for the tranga-website webserver to be configured to make the reverse-proxy requests directly but I think it's possible, we'd just have to do some testing with the docker networking settings itself. Either method is actually not too complicated of a change but as of right now we don't have branches to specifically test things that are docker/network specific which is really our only roadblock atm

YodaDaCoda commented 6 months ago

Okay I get what you mean. I added another location block to rewrite and proxy_pass requests to the /api location and it's working nicely. Thanks for the explanation and insights.

db-2001 commented 6 months ago

Would you mind sharing your configuration file for the Tranga specific stuff here so that those with setups similar to yours are able to get help as well?

YodaDaCoda commented 6 months ago

Sure here's my nginx conf. I'm using lsio's swag container.

tranga.subdomain.conf ``` ## Version 2000/01/01 # make sure that your tranga-api container is named tranga-api # make sure that your tranga-website container is named tranga-website # make sure that your dns has a cname set for tranga server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name tranga.*; include /config/nginx/ssl.conf; client_max_body_size 0; # enable for ldap auth (requires ldap-location.conf in the location block) #include /config/nginx/ldap-server.conf; # enable for Authelia (requires authelia-location.conf in the location block) include /config/nginx/authelia-server.conf; # enable for Authentik (requires authentik-location.conf in the location block) #include /config/nginx/authentik-server.conf; location / { # enable the next two lines for http auth #auth_basic "Restricted"; #auth_basic_user_file /config/nginx/.htpasswd; # enable for ldap auth (requires ldap-server.conf in the server block) #include /config/nginx/ldap-location.conf; # enable for Authelia (requires authelia-server.conf in the server block) include /config/nginx/authelia-location.conf; # enable for Authentik (requires authentik-server.conf in the server block) #include /config/nginx/authentik-location.conf; include /config/nginx/proxy.conf; include /config/nginx/resolver.conf; set $upstream_app tranga-website; set $upstream_port 80; set $upstream_proto http; proxy_pass $upstream_proto://$upstream_app:$upstream_port; } location ~ (/tranga)?/api/ { # enable the next two lines for http auth #auth_basic "Restricted"; #auth_basic_user_file /config/nginx/.htpasswd; # enable for ldap auth (requires ldap-server.conf in the server block) #include /config/nginx/ldap-location.conf; # enable for Authelia (requires authelia-server.conf in the server block) include /config/nginx/authelia-location.conf; # enable for Authentik (requires authentik-server.conf in the server block) #include /config/nginx/authentik-location.conf; include /config/nginx/proxy.conf; include /config/nginx/resolver.conf; set $upstream_app tranga-api; set $upstream_port 6531; set $upstream_proto http; rewrite ^(/tranga)?/api/(.*)$ /$2 break; proxy_pass $upstream_proto://$upstream_app:$upstream_port; } } ```
db-2001 commented 6 months ago

I appreciate you adding that but tbh I'm confused how it's working lol, the URI the front end calls doesn't have /api/ in it, that was just something I was giving as an example that would have to be implemented

YodaDaCoda commented 6 months ago

Oh so I'm effectively serving the frontend and backend on the same subdomain, and I use https://tranga.example.com/api in the frontend config for the API URL, and the nginx config directs URLs to /api/* to the backend.

db-2001 commented 6 months ago

Hey, I've made a few changes in the dev branch to try and get the nginx webserver for the front-end to reverse proxy /api/ to the backend and it doesn't work despite following a similar structure as yours. When you get a minute take a look at that branch and let me know if anything stands out to you.

YodaDaCoda commented 6 months ago

Sure I'll check it out tomorrow

YodaDaCoda commented 6 months ago

I made a couple changes to your nginx config.

nginx/conf.d/tranga.conf ``` - #access_log /var/log/nginx/host.access.log main; + access_log /dev/stdout main; + error_log /dev/stderr; location / { root /usr/share/nginx/html; index index.html index.htm; } - location ~ /api/ { + location /api/ { ```
  1. modified access_log and error_log so I can see the output in the docker log stream
  2. removed the ~ from the /api/ location because we're expecting it to be at the start of the url, not anywhere within it

With these changes in place, It Works On My Machine. The key parts I think I have set up to make it work are that the backend container is named tranga-api and they're both in the same docker network.

NB Hardcoding the upstream_* in the conf isn't great - it'd be better to expose an environment variable so the connection string can be configured by the container admin. link

db-2001 commented 6 months ago

Yeah I had it without the ~ at first too... And both my containers are in the same network and the docker containers have the appropriate names. When you say it's working on your machine, you mean you've pulled the dev image? Or do you mean that your third container works like that.

Also to your second point. Yeah once it is reliably working we can do the environment variables but I don't see those values ever changing so I didn't see the harm.

YodaDaCoda commented 6 months ago

Sorry disregard my previous, I realised I still had my swag container capturing the /api/ requests, testing further...

YodaDaCoda commented 6 months ago

@db-2001 I made a PR with the changes that ended up working for me. Bonus is putting the API_URL in the Dockerfile for you :) #69

db-2001 commented 6 months ago

Much appreciated! As you can tell this isn't my forte lol. I'd be happy to learn about the changes you made and why my version wasn't working, if you have the time to explain. I'll get this over in the Dev branch to start testing with

db-2001 commented 6 months ago

Noticed you deleted the configuration file, that was intentional?

db-2001 commented 6 months ago

Well it does seem to be working. I'm gonna keep this in the Dev branch for a couple weeks to see if anything else breaks before moving it over.

YodaDaCoda commented 6 months ago

Yeah I switched it over to the template instead. Not sure why git showed it as a delete and an add rather than just a rename. Not clear to me why, but I think the server_name directive was giving problems. I tried changing it to all sorts of things but I didn't really get anywhere until I just used the template to overwrite the default config.

I'm no docker/nginx expert, I mostly just use the linuxserver/swag container and its templates to add ssh/authelia to all my services.

db-2001 commented 6 months ago

Huh, good to know that this is still mostly black magic.

db-2001 commented 5 months ago

Officially merged into all branches, closing issue.

db-2001 commented 4 months ago

@YodaDaCoda the most recent cuttingedge containers seem to have broken the reverse proxying between containers. I don't think either Glax nor myself made any changes to them specifically. If you have time, I'd appreciate if you have any insight onto why it broke out of nowhere.

YodaDaCoda commented 4 months ago

@db-2001 reverse proxying seems fine, but initial load of the mangas was broken. the stringToColour function was defined as a const at the bottom of the file, which means it wasn't in scope at the time the setup() function was called. setup() managed to retrieve the list of mangas and store the number, but the later call to stringToColour threw an exception, so the view wasn't painted. then subsequent refreshes of the mangas did nothing, because monitoringJobsCount indicated there was nothing to update. #85