NGINX Reverse Proxy - CORS - Joplin

Hi!

Motivated by the homeserver series on the youtube channel I decided I want to give it a try. Using a NUC-like PC (x86) I utilize Fedora CoreOS and podman to host a number of applications. To make them reachable within my home network I want to use NGINX as a reverse proxy and define sub-domains to use the podman hosted applications.

tl;dr
Using nginx as a reverse proxy (no SSL) I can not reach the Joplin-application. Application responds with “Invalid origin” and google reveals only snake-oil like solutions or multiple docker-network stuff. After some extensive online-reading I come to the conclusion that it has something todo with CORS and the different HTTP headers. (i.e. If I add the joplin app_domain as an origin in the http header, app domain named by my configuration, I can get it to partially work in the sense that some elements are rendered, and some are blocked by the browser due to “CORS”-stuff. I expect some back and forth with subdomains in joplin that have the wrong origin in my nginx config …) Hence I am lacking deeper insight into this issue and the question is:
How does a valid generic nginx reverse-proxy config look like were the service that has to be be called expects a specific domain?
Help is much appreciated

Still here? Great, more info below.

Joplin expects a postgres server which is provided via podman as well, it can be reached, joplin can connect. All three components are bundled within a pod and the necessary ports are mapped within the pod. My (butchered) nginx configuration for this situation looks like this:

server {
            proxy_cache_valid 200 20m;
 
            #Listen to your public IP
            listen 80;
            server_name joplin.mydomain.org;
            #acces_log, error_log
           
            location /login {
                   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_set_header X-Forwarded-Port $server_port;
                   proxy_set_header X-Forwarded-Host $host;
                   client_max_body_size 400M;
                   proxy_pass http://127.0.0.1:7002/login;
               }

               location / {
                   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_set_header X-Forwarded-Port $server_port;
                   proxy_set_header X-Forwarded-Host $host;
                   client_max_body_size 400M;
                   proxy_pass http://127.0.0.1:7002$request_uri;
               }    
           } # end server

As you can see I already tried some stuff, following blindly posts on the internet …

The joplin configuration is defined in an env - file

          APP_BASE_URL=http://joplin.mydomain.org
          APP_PORT=7002
          DB_CLIENT=pg
          POSTGRES_PASSWORD=joplin
          POSTGRES_DATABASE=dbJoplin
          POSTGRES_USER=joplin
          POSTGRES_PORT=5432
          POSTGRES_HOST=localhost
          # Seems a host resolving is to blame for this - https://github.com/laurent22/joplin/issues/5048
          RUNNING_IN_DOCKER=0

passed to the container.

Some people on the internet claim that the APP_BASE_URL has to be the same as the sub-domain, hence the the value
Furthermore, all the “it now works” - questions on the internet regarding the joplin applications have in common that the outer call, the one to nginx, is an https one, were the one to joplin is then only http. My gut-feeling is now that with the switch from https to http, stuff happens within the header that is pleasing the application. I want to to do it step-by-step and only want to start with a pure http-solution.

Could someone elaborate whats going on behind the scenes when a reverse proxy is in play and what the CORS - stuff is all about; I am a little bit lost here. For me it seems an over-engineered approach, but this is 100% due to the lack better knowledge.

And just to be clear, I don’t blame joplin, it is I that needs to know more about that stuff.

Thx.

1 Like

Soooo… I’m not sure this isn’t a bug in Joplin.

CORS exists to prevent xsrf, it helps to prevent e.g. Joplin stuff from being manipulated outside of it’s intended domain, e.g. by an actively exploited forum you’re visiting.

Access-Control-Allow-Origin is the interesting header, and I assume Joplin sets it based on APP_BASE_URL.

What happens when you set APP_BASE_URL to https://… does Joplin start requiring a cert to start-up? Is there a way to separate Joplin’s headers from its http server settings? (Inability to do so would be what I’d call a Joplin bug).

Hmm there is definitely something going on with my nginx setup; for example adding other subdomains creates the situation were only the first server entry is being processed …

Https might also be an issue, I will check and report back

Ok, I have to blame myself (of course)
For testing reasons I added the domain to my /etc/hosts file and created a mixup in terms of subdomains. The subdomain was handled as if it was the “main” domain

Thus my config on joplin was correct, the call was not …

I guess next up is a custom DNS to avoid such problems in the future

1 Like