I am deploying the 7.0.1 docker image to Kubernetes. The container starts up without error.
However, I will access the portal behind a reverse proxy. For instance, the public base URL will be something like: https://mydomain.com/openemr/. This gets forwarded then to the internal IP address, something like http://192.168.x.x/.
I canāt speak to application-level assistance here, but if youāre willing to tinker with the image, look at the ProxyPassReverse directive for Apache.
(Alternatively, if you front the openemr container(s) with your own load-balancing Apache server you can apply it that way.)
As an alternative, I think I could ātrickā it into working if I could make the base paths the same. Is there an option to set a base path in OpenEMR? i.e. So it doesnāt stand up on http://localhost/ but rather http://localhost/{somepath} ?
Iād prefer to not have to manipulate the image if possible. Environment variables are easy to set in a docker container when deploying to kubernetes, so that is preferred.
Weāre not exposing any kind of functionality through the Docker envvars, I know that much.
You know what? If youāre not willing to meddle with the image, which is fair, maybe you need to extend it. That would probably work okay and I need to spend more time pushing people about this anyways. Apacheās already installed, after all.
So my advice is:
Create a new container FROM openemr:7.0.1
Create a script that patches or replaces the Apache configuration file openemr.conf copied into the image by the parent container
Inject and run that script in the Dockerfile and then reprise the CMD directive to launch the revised container with openemr.sh
Build, tag, and push your revised image to a container repo, public or otherwise
Consume your image instead of the stock image for Kubernetes
I will note, as the Docker image starts to get more interest from users for non-dev deployments, I suspect this will become an issue for more folks. Many deployments I suspect will attempt to run OpenEMR behind a reverse proxy, gateway, WAF, etc. where the public URL path wonāt match the internal base path.
I was hoping that there was an ENV var that Apache, or OpenEMR would pick up to modify relative URLs and redirects, but so far coming up short.
If I figure something out Iāll report back.
It gets confusing to research this, since Apache can also be configured and used as a reverse proxy. But in this case Apache/OpenEMR is running behind a reverse proxy.
Anyway, my reverse proxy is forwarding traffic to OpenEMR. Traffic hits my public URL at something like https://mydomain.com/openemr/*, and the proxy forwards it to the internal instance which would be running on a local address unaware of the rest of the network topology - something like http://192.168.1.100/*
When OpenEMR redirects to a new URL, it is correctly keeping my public hostname - it must be detecting it from one of the headers, but it is not aware that the base path is different. So instead of redirecting (for instance) to the setup at https://mydomain.com/openemr/setup.php, which my proxy would know to route to http://192.168.1.100/setup.php , it is redirecting to https://mydomain.com/setup.php - which my proxy doesnāt know how to handle.
The proxy is handing traffic for many different services, so it needs distinct paths for each to route them.
I believe I can do as suggested and edit the Apache config files to make it aware, but this is not ideal in the container world. You can make a custom image per deployment environment (not ideal), or you can inject the config file at deployment time, which requires some hoops to jump through because mounting a config map directory in Kubernetes doesnāt preserve the existing directory if it exists in the image - so you have to mount it to a different location and use an init container to copy it to the correct location (if there are other files in it you need to preserve).
And in both cases I then have to maintain the file - as OpenEMR changes the Apache configs in future versions I have to keep my custom version up to date.
Whereas with environment variables, it is very easy to set them at deployment time so distinct deployments can have different values and share a common image - like is currently possible with the DB connection settings.
Anyway, if this is all handled on the Apache side there may not be anything you can do about it. I just keep thinking that running a LAMP stack in a container isnāt anything novel, so there must be some easier option Iām missing.
Also, in kubernetes, there is a neat workaround to not bash the entire directory when mounting a config map (this is also an issue I ran into on the Kubernetes stuff for OpenEMR and can see the workaround here: https://github.com/openemr/openemr-devops/blob/master/kubernetes/phpmyadmin/deployment.yaml#L29-L31). That being said, the goal is that the reverse proxy should be able to manage this, which is why curious what you are using as the reverse proxy.
Iām using Azure API Manager currently in a reverse-proxy role here. But it could be any kind of gateway in this scenario that is routing traffic from the outside to the inside.
Iām not clear how the reverse proxy would mange this scenario, but my understanding may be incomplete.
My understanding is that a reverse proxy only handles traffic in one direction - traffic hits the proxy, and based on rules (usually the URL paths), it routes it to where it needs to go. If the service that it routes to re-directs to a new URL, the proxy is not aware of this unless the redirect is to a URL that also hits the proxy - at which point it uses itās rules to again route it to the proper place.
Herein lies my problem, the redirected URL doesnāt contain the path that my proxy needs to route it - back to my OpenEMR instance.
Unless you are thinking that the reverse proxy should be setting some headers that Apache/OpenEMR would utilize to properly construct the URL paths? That could be the case - the Forwarded, and X-Forwarded headers, etc.
Just as an example from another project - Keycloak has various options to handle this scenario, if you scroll down to the āDifferent context-path on reverse proxyā section here:
Thatās essentially what I was hoping to find, either a way to set the context path of OpenEMR so it would match the path exposed by my reverse-proxy, or a way to explicitly tell it that path so it uses it to construct the urls as you navigate around.
My take on that is that the reverse proxy (which apache reverse proxy would do via the ProxyPassReverse Directive setting) can be set to manage this situation (ie. then nothing would need to be done on the docker itself). Let me know if my assumption is incorrect.
Also, pretty sure a reverse proxy is 2 way (ie. both the request and response pass through it). I just read through following article to review reverse proxy mechanism (this article also posted quick example of setting up reverse proxy in apache and it seems like Azure API manager should also be able to so something like ProxyPassReverse setting when in reverse proxy role).
You may be correct Brady, Iām not 100% certain. Iāve worked with several components that allow you to hardcode the public base URL or path to achieve a similar result - but perhaps this is because itās simpler than trying to get a reverse-proxy to rewrite the headers (and potentially in-page links) generated by a site.
I played around today with getting the Apache server in the OpenEMR docker container to do this, but no luck so far. So far I was trying to use the existing OpenEMR image and simply inject a custom openemr.conf file with the āProxyPassReverseā directive . But I havenāt been able to get it to work yet. ProxyPassReverse requires some modules to be loaded, and when I try to do so Apache fails saying it canāt find them.
i.e. Iām trying to add:
Starting apache!
httpd: Syntax error on line 482 of /etc/apache2/httpd.conf: Syntax error on line 3 of /etc/apache2/conf.d/openemr.conf:
Cannot load modules/mod_proxy.so into server: Error loading shared library /var/www/modules/mod_proxy.so: No such file or directory
And indeed if I inspect the container there are many modules in the /modules directory, but not this one. (Iām an Apache novice).
So maybe Iād need to rebuild a custom OpenEMR image as was suggested earlier so I can install those modules.
Or try to get my reverse proxy to do this work, rewriting the Location header, page links?, etc on the outbound responses.
Pretty sure those directives are for the reverse proxy (when using apache as a reverse proxy).
I think most straightforward way to get what you want in the apache openemr.conf in the openemr docker (in kubernetes could overwrite that file with config map if donāt want to build a separate docker) is to change the: DocumentRoot /var/www/localhost/htdocs/openemr
to DocumentRoot /var/www/localhost/htdocs
If do above, just make sure there are no ābadā scripts in /var/www/localhost/htdocs that may cause security vulnerabilities. Another way that may work (that would not allow public web access to /var/www/localhost/htdocs) would be to use an alias in apache: Alias "/openemr" "/var/www/localhost/htdocs/openemr"