I’ve recently begun trying to Dockerize my services and I’m to the point of Dockerizing everything that already has an image built. Now I’m trying to build an image for facileManager (FM) which doesn’t yet have one. I’ve got it mostly working but I’m having an issue when running it behind Nginx. FM is normally an apache-php app and doesn’t include install instructions for Nginx. What I’ve noticed with my container/image is that it works ok when I connect directly to it through a published port but if I try to connect to it through Nginx it errors out complaining about the .htaccess file not working. I’m not an expert in either Apache or Nginx so I did my Googleing but didn’t come up with much beyond WordPress having a similar issue with it’s "pretty urls" so I’m hoping someone here can give a hand.
First here is the Github repo for the app: https://github.com/WillyXJ/facileManager/tree/ea159f5f6112727de8422c552aa05b6682aa4d79/server
The .htaccess file specifically is:
<IfModule mod_headers.c>
<FilesMatch ".(js|css|txt)$">
Header set Cache-Control "max-age=7200"
</FilesMatch>
<FilesMatch ".(jpe?g|png|gif|ico)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
The exact error I’m getting is from here:
https://github.com/WillyXJ/facileManager/blob/ea159f5f6112727de8422c552aa05b6682aa4d79/server/fm-includes/init.php#L153
if (!defined('INSTALL')) {
if (@dns_get_record($_SERVER['SERVER_NAME'], DNS_A + DNS_AAAA)) {
$test_output = getPostData($GLOBALS['FM_URL'] . 'admin-accounts.php?verify', array('module_type' => 'CLIENT'));
$test_output = isSerialized($test_output) ? unserialize($test_output) : $test_output;
if (strpos($test_output, 'Account is not found.') === false) {
$message = sprintf(_('The required .htaccess file appears to not work with your Apache configuration which is required by %1s. '
. 'AllowOverride None in your configuration may be blocking the use of .htaccess or %s is not resolvable.'),
$fm_name, $_SERVER['SERVER_NAME']);
if ($single_check) {
bailOut($message);
} else {
$requirement_check .= displayProgress(_('Test Rewrites'), false, 'display', $message);
$error = true;
}
} else {
if (!$single_check) $requirement_check .= displayProgress(_('Test Rewrites'), true, 'display');
}
}
}
Nginx config:
server {
listen 80;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name bound.example.com;
ssl_certificate /etc/nginx/ssl/live/bound.example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/bound.example.com/privkey.pem;
include /etc/nginx/ssl/options-ssl-nginx.conf;
ssl_dhparam /etc/nginx/ssl/ssl-dhparams.pem;
location / {
proxy_pass http://FM.; <<< Docker service name
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
}
}
My Dockerfile/commands run: https://github.com/MeCJay12/facileManager-docker
FROM php:7.4-apache
ENV TZ=UTC
ENV Version=4.2.0
ARG DEBIAN_FRONTEND=noninteractive
WORKDIR /src
RUN apt-get update
&& apt-get -qqy install wget libldb-dev libldap2-dev tzdata
&& wget http://www.facilemanager.com/download/facilemanager-complete-$Version.tar.gz
&& tar -xvf facilemanager-complete-$Version.tar.gz
&& mv facileManager/server/* /var/www/html/
RUN ln -s /usr/lib/x86_64-linux-gnu/libldap.so /usr/lib/libldap.so
&& docker-php-ext-install mysqli ldap
&& a2enmod rewrite dump_io
COPY php.ini /usr/local/etc/php/php.ini
RUN rm -r /src
Bonus question: When accessing this container/image directly through a published port, the images are all broken. I assume it’s related since the .htaccess file includes references to images files.
Thanks in advance for the help!
2
Answers
Found solution in https://github.com/WillyXJ/facileManager/issues/491. Needed to remove a check in the webapp that wasn't working quite right.
Dot Points:
Below is the configuration file I use to reverse proxy through to a Ubiquiti Unifi container. All my certbot is handled off site so I need not consider that here. If you compare our location blocks, the issue will likely become immediately apparent, but I’ll explain for clarity’s sake.
What you need to look at is your Proxy Pass directive. This is of course where the magic proxying happens. I notice that you have not been including the $request_uri, so any request nginx receives for
bound.example.com/testpage1
, it will send a request to the upstream apache server forbound.example.com
. Of course if you need to include a port, as I have done here8443
, this is the place to do it also.If you include this variable, it should resolve your problem.
The following does not answer your question, but I thought I would include it also just as some helpful information.
Also, I just want to note that I have included a resolver. The IP address 127.0.0.11 points to Docker’s internal DNS resolver. Chances are you won’t need to include this, however I did so myself to ensure I didn’t get odd problems.
Lastly, I’d just like to recommend that you look into upgrading your SSL settings, to ensure that you are safe from attacks from weaker SSL / TLS versions.
I expect that adding the variable $request_uri to your proxy pass directive is all that is required to get your site working.
ADDITIONALLY
Further to the above, I have had a chance to test this out in my own environment and was able to get it working, seemingly (although I did not go through the install procedure). I found that there would be no DNS entry in the docker resolver if I did not declare a network address on the docker network stack for this container. I used the following docker configuration;
where the directory boundexample pointed to a local copy of your github repository. My nginx configuration was the same as you provided, only I modified for my own SSL and used the following in my location block;
It is also possible that using FM in upper case within your docker configuration may cause you problems, I was unable to use upper case myself as docker-compose would not permit it.