Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
YodaDaCoda opened this issue Feb 27, 2024 · 20 comments
Closed

Comments

@YodaDaCoda
Copy link

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
Copy link
Collaborator

db-2001 commented Feb 28, 2024

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
Copy link
Author

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
Copy link
Collaborator

db-2001 commented Feb 28, 2024

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
Copy link
Author

YodaDaCoda commented Feb 28, 2024

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
Copy link
Collaborator

db-2001 commented Feb 29, 2024

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
Copy link
Author

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
Copy link
Collaborator

db-2001 commented Mar 6, 2024

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
Copy link
Author

Sure I'll check it out tomorrow

@YodaDaCoda
Copy link
Author

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
Copy link
Collaborator

db-2001 commented Mar 6, 2024

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
Copy link
Author

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

@YodaDaCoda
Copy link
Author

@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
Copy link
Collaborator

db-2001 commented Mar 7, 2024

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
Copy link
Collaborator

db-2001 commented Mar 7, 2024

Noticed you deleted the configuration file, that was intentional?

@db-2001
Copy link
Collaborator

db-2001 commented Mar 7, 2024

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
Copy link
Author

YodaDaCoda commented Mar 7, 2024

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
Copy link
Collaborator

db-2001 commented Mar 7, 2024

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

@db-2001
Copy link
Collaborator

db-2001 commented Mar 30, 2024

Officially merged into all branches, closing issue.

@db-2001 db-2001 closed this as completed Mar 30, 2024
@db-2001
Copy link
Collaborator

db-2001 commented Apr 22, 2024

@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
Copy link
Author

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants