Orthanc Explorer 2 behind a reverse proxy with <Location>?

We host a lot of Orthancs for different research groups, run in parallel in Docker (Osimis image) and all hosted on the same machine behind an Apache reverse proxy with unique sub-url settings for each group. For example, http://some.machine/orthanc1 for group1, http://some.machine/orthanc2 for group 2, etc.

That setup works great for us.

I thought I would try the new Orthanc Explorer 2 interface, but out of the box, I cannot get it to work with our reverse proxied setup. Is it possible that the node application behind the scenes was built assuming it had top level access to the host?

http://some.machine/ <— Does the OE2 plugin bundled in the Osimis Orthanc Docker image think it runs here?

If I pull up the developer console in the browser, I see a series of errors about javascript and CSS files not found.

For the moment, I am just asking if it is expected to work in this scenario (reverse proxied to a sub url). If it is, then I will go off and dig deeper into my reverse proxy configuration to see what I can fix. Or I’ll increase the logging to see if Orthanc can tell me anything on the back end.

I’m also content to wait if it just doesn’t support the sort of setup I run.

Thanks,
John.

I went and pulled up the Dockerfile Osimis uses to build their images.

Under the section building Orthanc Explorer 2 with node, I don’t see anything that specifically references the URL path.

I suspect I will need to dig a little further.

Responding to a direct email response to my post here, let me clarify my setup.

I am using the Osimis docker image for Orthanc that comes with a number of plugins pre-installed and configured by way of environmental variables at the time of the Docker container launch.

Because I run multiple different Orthancs on the same docker host machine, I allocate a sub-URL to each using Apache for reverse proxy and a <Location /sub-URL/> configuration that assigns the sub-URL.

This approach has worked fine, likely because Orthanc internally was written to refer to itself internally with relative rather than absolute URLs.

Where this reverse proxy with a sub-URL can get into trouble is with web apps that were written using absolute URL paths, basically assuming the app is running on the top level main host URL.

I recently started looking at the Orthanc Explorer 2 plugin. I can make it work when I run the Orthanc at the top level host URL (ex. http://127.0.0.1:8042) but not if I redirect via Apache reverse proxy with to a sub-URL (ex. http://my.proxy/sub-URLhttp://127.0.0.1:8042/). Doing so generates a number of errors from basic 404 errors to javascript errors. The Orthanc (and the legacy explorer page) runs just fine behind the proxy, but the OE2 plugin does not.

Reminder: This is all within the context of the Osimis Docker image. I am not building OE2 myself, but using the image pre-built plugin.

My first guess was that the Osimis compilation of OE2 that they bundled into their Orthanc docker image assumes the Orthanc is running at the top level URL. So I have been digging into the Docker file.

Or, I simply am not sophisticated enough with my reverse proxy settings to get the plugin to behave on a sub-URL.

I have tried using the environmental variables to control the Docker container, including different settings for the OE2 root directory. I have the best (although still incomplete) response when I set the OE2 root to reflect my sub-URL. At least the 404 errors go away, but then the plugin crashes with javascript errors (undeclared variables, unexpected zero valued fields, etc.)

I have seen similar behavior before with other node/npm based apps. My intuition is that I will need to rebuild the OE2 node app myself with my sub-URL baked in. That, or I learn more sophisticated rewrite rules using Apache to fix the proxying back and forth.

I could post my current error messages and will if someone wants them. I don’t think they are that informative. At the moment, I would be happy to work out the kinks myself if I could get confirmation as to whether the OE2 app assumes it is running at the top level URL or not. Knowing that would give me a better idea how to tackle the problem I created for myself with sub-URL proxying.

Sorry about the private message. Your setup does seem a little complicated, although I’ve seem some that are similar.

What you mention about the relative vs. absolute urls might be part of the problem. If you are using one method, you might try the other.

I have a client with a setup that is probably similar, with 5 instances of Orthanc running as separate containers in Docker. If they are all running in Docker, they can “talk” to each because you have the IP or container names for the instances.

As far as explorer2 is concerned I think it runs on the CIvetWeb server that is part of Orthanc, so it runs in that instance of Orthanc, and I think ‘assumes’ that the Orthanc backend is the one also running in that container.

Early on, I think Osimis or Orthanc had a configuration option within the OE2 config to allow configuration of the API target for OE2. Alain would need to chime in about that, but I think so. I don’t see that in the current config setup.

With your setup, you might consider hosting and developing your own version of the OE2 package, either using the ServeFolders Plug-in within Orthanc, or on your Apache or an NGINX or NodeJS server. That would give you some flexibility in dynamically changing which Orthanc Instance the OE2 front-end is connected to, possibly with a HEADER parameter, token, a COOKIE, etc. There would be a number of ways to do that.

That would also give you some other possibilities for customizing and developing the OE2 front-end, which isn’t that difficult really if you have experience with Vue.js. Many of the backend calls are already part of that package.

Another option might be to "dynamically pick” the appropriate backend Orthanc Instance in the proxy, although I use NGINX, not Apache.

/sds

I might have been think about this:

// Prefix URL of the orthanc public API
// This is useful if, e.g, your Orthanc is behind a reverse-proxy. “OrthancApiPublicRoot”: “/”,

I think they removed now: See:

https://github.com/orthanc-server/orthanc-explorer-2/commit/7353ab77d4c05655088d81adda14b51a1a8a5ab4
https://github.com/orthanc-server/orthanc-explorer-2/commit/d6ae1eda57e312564a14e98e3948c5ace6b8033b

/sds

That OrthancApiPublicRoot is probably what I was looking for. :slight_smile: I wonder if they consolidated that functionality into the main OE2 root parameter?

I see the setting for the OHIF viewer. That’s one of those web apps that I find absolutely insists on running at the top level root directory of the server or at least the OHIF Docker image makes this a requirement. I’d love to know if anyone has ever managed to proxy that to a deeper sub-URL, but I should start a different topic for that and not muddy this one.

Hi John,

Are you getting this type of error ?
If yes, this is not related to reverse proxying but to an issue introduced in OE2 0.8.0 (that I just fixed).

This reverse-proxy sample works with osimis/orthanc:23.3.0, does not work with 23.3.3 but should work again with 23.3.4 that will be available later today.

Best regards,

Alain.

Here are the errors I am currently seeing. At one point, my read of an earlier message suggested that the available languages array was coming up empty. So that is why I define it in the Orthanc json file at the moment. I let the OE2 root be the default, though obviously the client is going to report the proxied sub-URL.

FYI, I am running one of my docker setups based on the recipe here.

This is in a chromium based browser, Vivaldi.
oe2_page.png
oe2_console.png

Hi John,

Do you still have the issue with osimis/orthanc:23.3.4 that has just been released ?

Best regards,

Alain.

oe2_console.png

oe2_page.png

I typically pull the “latest” tag from dockerhub. My most recent pull was from 4 days ago.

I can rebuild based on the most current “latest” and get back to you.

I just rebuilt my setup based on the latest osimis image and it appears to work. You must have addressed whatever was causing this issue between my pull at the end of last week and today!