cu / silicon

Silicon Notes, a web-based personal knowledge base with few frills
Other
220 stars 7 forks source link

Silicon Notes doesn't work as subfolder proxy with nginx #3

Closed SwissOS closed 1 year ago

SwissOS commented 1 year ago

hi,

First of all, thank you very much for this note taking webapp. It's simple and beautiful.

I have selfhosted your nice project on my raspberry pi. I use nginx proxy manager and installed Silicon Notes with docker. It works perfectly on a standalone basis (localhost), but I want to be able to reach it from the web as a subfolder of my domain (for example: www.domain.com/silicon).

Unfortunately, I couldn't configure the nginx proxy for that. Is it not possible? I get an error 404.

As a workaround, I set it up as a subdomain (silicon.domain.com) and that works perfectly with nginx.

cu commented 1 year ago

Thank you, it's nice to hear you're enjoying it. :)

I'm not familiar with Nginx Proxy Manager (it's on my todo list), but I do know Nginx. It's entirely possible that Silicon may require some changes to allow being hosted under a subpath, but I'd like to be able to reproduce what you're seeing before spending much time poking at it.

Is it possible to paste your Nginx configuration for the site? Or, perhaps even better:

Are you using docker-compose? If so, can you paste a docker-compose.yaml that reproduces the problem?

SwissOS commented 1 year ago

Well, it's not as simple as giving you a docker-compose.yaml file. I use SWAG from linuxserver.io, which is a container that includes several things, amongst which Nginx Proxy Manager (NPM). It requires several configuration files underneath (your domain name, name server for letsencrypt certificates, and of course NPM config files).

But for NPM in particular, I was using this conf:

location ^~ /silicon-notes {
    include /config/nginx/proxy.conf;
    include /config/nginx/resolver.conf;
    set $upstream_app silicon-notes;
    set $upstream_port 5000;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}

Which is a pretty standard NPM conf file for subfolders. The only "strange" thing is that you need variables, otherwise SWAG cannot resolve the container name (silicon-notes). Even though I use docker-compose and all the containers run in the same docker network, somehow, this is a bug/feature of SWAG.

Don't fret over this issue, I got it working as a subdomain, as a workaround for now.

What reverse proxy are you using on your host?

cu commented 1 year ago

I'm using Caddy with basic auth, the deployment looks like this: https://github.com/cu/web

Got a little nerd-sniped on this one but I think I figured out what's going on. I'm not familiar with SWAG but I was able to replicate the issue with a minimal nginx config. Thanks to this article, I found that setting a URL prefix only requires minor changes to the nginx config and docker-compose file, in particular, the URL prefix must appear in the proxy_pass statement, and it must also be passed along to gunicorn (via SCRIPT_NAME). And to prevent the healthcheck from causing tracebacks, it has to be overridden in the docker-compose config as well.

So I believe the nginx proxy_pass statement should look like this:

proxy_pass $upstream_proto://$upstream_app:$upstream_port/silicon-notes;

And these need to be set in the silicon-notes container in docker-compose.yaml:

    environment:
      SCRIPT_NAME: /silicon-notes
    healthcheck:
      test: curl http://localhost:5000/silicon-notes/view/home || exit 1
      start_period: 10s
      timeout: 5s

If you don't care about the healthcheck (which is quite reasonable, this arguably does not need one), then you can also just disable it with:

healthcheck:
  disable: true

I added a short blurb to the README pointing to this issue in case others want to do the same thing. I'd like to close this issue but if you happen try this again and run into problems, it can be reopened.