Joplin server w/nginx setup with one problem

I have Joplin server 2.10.5 setup on my LAN via docker running on Ubuntu. It looks great, I'm excited to get started using it! Thanks to all the hard work of you who are involved in its development!

I do have one final issue due to my naivety of the infrastructure that I'm trying to resolve. I want to access my joplin from outside my LAN. I am using a NAS (Synology) which has its own reverse proxy (nginx) which operates within a proprietary VPN. So I've setup a sub-domain with a cert and nginx to send outside requests from my Synology subdomain ( over to my internal server (which is working fine from The good news is, it does reach the server but then I get all sorts of mixed content:

The first call (1) to login gets a 200.

But then problems arise with loading the content:

The other calls all have the external https address as the origin.

If I changed APP_BASE_URL from the current local base url ( to the full external URL ( I get the dreaded Invalid origin error.

Am I missing some type of nginx headers to address this cross-origin error? Here's my nginx configuration:

server {

        location / {
            proxy_set_header Host;
            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;

If I continue with my login, it complains about not being secure:

Then I get an Invalid URL and a 500 error from the local server on the login request.

I was under the impression that with nginx I do NOT need a cert on my internal server, is that correct?

Hope someone can give me some pointers here. Thanks!

The APP_BASE_URL has to be the one which you are using to connect to the server, so in your case Did you take a look at this guide?

About your cert question: The nginx server needs to be configured with the cert of your subdomain, however the server on which joplin is running does not need anything, as it only uses http.

If none of the above helps, maybe provide your docker-compose.yml for further help.

Thanks, @MrKanister, I did come across that guide but I thought I was so close it would just be a minor change somewhere. I tried changing the APP_BASE_URL but I get the Invalid origin error both from the local IP address as well as from the https://joplin... address.

I don't have a docker-compose file because I already had postgres and nginx installed. The only thing I needed to do other than firewall was to use the docker image calling it like this:

docker run --env-file .env --net=host joplin/server:latest

My .env file looks like this:

# works locally but mixed content errors accessing via external https address
# gives invalid origin error


My gut is telling me it has something to do with how nginx is sending traffic through. The nginx server does have the necessary subdomain cert so thanks for confirming that I don't need that on the actual joplin server host.

I read another case just like mine where he makes the point that from the server perspective, the local IP address is the APP_BASE_URL, which made sense to me. However, he had a very complex solution which I don't want to follow because my case is very out-of-the-box and seems like it's just something I'm not understanding.

For example, doesn't it make more sense that if my server is proxied then from its perspective the APP_BASE_URL should be the local IP address? I don't have the https://joplin.yadda... cert on that joplin host.

You won't be able to access joplin both via external and via internal ip (both is also possible, but that's another topic). Your goal should be that joplin is accessible from external but not from internal.

This implies that the APP_BASE_URL has to be the public url. The variable is for the server, so that it knows where to redirect, fetch the resources etc. If this would be the internal address those references to local ips wouldn't work from external.

In your first post you stated, you had already tested the server standalone, right? So APP_BASE_URL set to and then accessing the server via that If so, then it's almost certainly the fault of nginx. I didn't use nginx to this point, so I can't really support you with that...

Is the joplin server log saying anything interesting when you are getting the invalid origin error?

The solution you linked doesn't look very trustworthy from my perspective, but if it works for him, it's fine, I guess...

Just a reassurence: The server_name url ( and the urls you are using elsewhere (, are the same, correct?

OH, ok, I wasn't aware that I can only access from the internal OR the external address so if that's the case, I agree that it would follow that APP_BASE_URL would need to be the external address.

The server log doesn't give much, in fact, the only request it shows is the /login which is successful:

2023-02-20 22:00:45: App: GET /login (200) (2ms)
2023-02-20 22:05:55: App: GET / (302) (1ms)
2023-02-20 22:05:55: App: GET /login (200) (1ms)
2023-02-20 22:06:08: App: GET /login (200) (0ms)

It doesn't show anything else. If I login locally (the http/local address), it shows all the requests:

2023-02-20 22:08:00: App: GET /login (200) (1ms)
2023-02-20 22:08:00: App: GET /css/bulma.min.css (200) (1ms)
2023-02-20 22:08:00: App: GET /css/fontawesome/css/all.min.css (200) (2ms)
2023-02-20 22:08:00: App: GET /js/jquery.min.js (200) (1ms)
2023-02-20 22:08:00: App: GET /css/main.css (200) (5ms)
2023-02-20 22:08:00: App: GET /js/main.js (200) (0ms)
2023-02-20 22:08:00: App: GET /images/Logo.png (200) (1ms)
2023-02-20 22:08:19: App: POST /login (302) (83ms)
2023-02-20 22:08:19: App: GET /home (200) (3ms)
2023-02-20 22:08:19: App: GET /css/bulma.min.css (200) (7ms)
2023-02-20 22:08:19: App: GET /css/fontawesome/css/all.min.css (200) (3ms)
2023-02-20 22:08:19: App: GET /js/jquery.min.js (200) (2ms)
2023-02-20 22:08:19: App: GET /js/main.js (200) (4ms)
2023-02-20 22:08:19: App: GET /css/main.css (200) (1ms)
2023-02-20 22:08:19: App: GET /css/index/home.css (200) (2ms)
2023-02-20 22:08:19: App: GET /images/Logo.png (200) (1ms)
2023-02-20 22:08:19: App: GET /css/fontawesome/webfonts/fa-solid-900.woff2 (200) (1ms)

Regarding the various external URLs: yes, you're correct. All of those refer to my registered sub-domain. I just confusingly used numerous stand-ins for the actual.

I'll mess around more with the nginx config and see if I can discover anything new. Thanks for your help!


Ok, just an update. I didn't get back to configuring nginx but in the meantime came across an article on tunneling using Cloudfare. I setup Cloudfare (very simple) and am now able to access joplin through my domain. Thanks, @MrKanister for your assistance.

For others facing this issue (stemming from Invalid Origin), consider if this solution is right for you. I think for my configuration it comes down to the nginx setup. Something I was missing was creating a problem. Contrary to my initial belief it doesn't appear possible to run OOTB joplin server via docker both via your local IP address and through your secure external, encrypted domain (see post above). In any case, all working now very handily!


1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.