Reputation: 303
I installed phpMyAdmin docker image and run it with
# docker run --name phpmyadmin -d --link mariadb:db -p 8081:80 -e PMA_ABSOLUTE_URI=http://servm3/pma --restart unless-stopped phpmyadmin/phpmyadmin
Accessing http://servm3:8081 works fine. The variable PMA_ABSOLUTE_URI is for reverse proxies as seen on the docker page.
Then I set up nginx (locally installed, not inside docker) to act as a reverse proxy (working for several other apps like guacamole).
Inside my nginx.conf I have:
location /pma/ {
proxy_pass http://localhost:8081/;
proxy_buffering off;
}
Accessing http://servm3/pma shows the favicon on the browser tab but instead of the login page only a blank page is shown. Removing the preceding "/" and restarting nginx only gives a 404.
# docker logs phpmyadmin
shows nothing except from the php and nginx service start info, nothing related to phpmyadmin.
Local nginx access log shows several 304 and 404 codes and some 200, error log is not present. Detailled log can be found here on pastebin.
I hope somebody will be able to tell me how to make nginx work as a reverse proxy for the phpMyAdmin docker container.
If some important information is missing please let me know.
Upvotes: 16
Views: 22300
Reputation: 28722
If you have a docker setup that will have many different domains but one database(like a multistore magento shop, or a multi domain wordpress) it might be undesireable to forward all the traffic to one single domain. Or even having to hardcode it in the ENV variable.
It's easier to portforward based on subdomain.
In your nginx config define a map, listing your port numbers
map $subdomain $port_number {
default "013";
phpmyadmin "014";
mailhog "017";
}
This will make it so that when the variable $subdomain
matches any entry in the map below, the variable $port_number
will be set to the corresponding value. In my example is default "013"
if nothing is matched.
Then add the following directive to your server directive.
server_name server_name ~^(?:(?<subdomain>[^.]+)\.|)(?<base_domain>.+\.localhost)$;
These regexes set 2 variables $subdomain
and base_domain
If the request is example.com.localhost
$subdomain
will have example$base_domain
will have com.localhost$port_number
will have 013If the request is example.com.localhost
$subdomain
will have phpmyadmin$base_domain
will have example.com.localhost$port_number
will have 014[Optional] If you need the actual domain in a variable you could use an if statement like this:
set $lookup_domain $host;
if ($port_number != "013") {
set $lookup_domain $base_domain;
}
and $lookup_domain will contain the actual domain you're interested in.
You can then use a proxy pass like this:
location / {
proxy_pass http://docker-host:${backend}${port_number};
proxy_pass_header Content-Type;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # allow websockets
proxy_pass_header Connection;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
Where the $backend
variable contains in my case the base port range for my webapp set.
So the proxy url becomes someting like http://docker-host:20013 depending on the app. Feel free to skip that and set the ports to actual ports or whatever, or to modify it to follow any other logic.
Upvotes: 0
Reputation: 41
Don't need rewrite.
nginx.conf:
location ^~ /pma/ {
proxy_pass http://pma-container/;
absolute_redirect off;
}
docker-compose.yml:
PMA_ABSOLUTE_URI: https://yourdomain.com/pma/
Notice: keep trailing slash on location
, proxy_pass
, PMA_ABSOLUTE_URI
Upvotes: 4
Reputation: 168
don't know if you're still looking for an answer.
just follow this answer from Joshua Ostrom.
The problem is I dont know why it doesn't behave like it should but, you need to add index.php at the end like https://yourdomain.com/pma/index.php
.
I had the same issue
Upvotes: -1
Reputation: 1245
There's not a lot that can be done. Problem is that phpmyadmin is serving its pages from localhost, and even if nginx translates accesses from http://servm3/pma
to http://localhost
, all links in HTML content ignore the lattest and, even if they're relative, they don't take into account the /pma
part. So, all those 404 errors you're seeing are from resources that, inside HTML, are referenced as relative links like styles.css
, that when referenced/clicked become http://servm3/styles.css
, that doesn't exist in the server.
Unfortunately reverse proxies work at the header level so, even if they are able to change headers like Location
on the fly, they leave HTML content untouched, and hence the problems. There're workarounds involving changing HTML code on the fly, but they're not easy, are unreliable at most and they hinder performance considerably, so the only practical solution is that websites explicitly support some kind of base path setting. In this case, the solution would be that phpmyadmin Docker image allowed setting the base path using an environment variable in docker-compose.yaml
, instead of defaulting to root.
Another workaround in the mean time would be not using a relative path, but a subdomain. If you're in control of DNS settings for servm3
, you could use something like phpmyadmin.servm3
, and proxy_pass without problems.
Upvotes: 1
Reputation: 451
Be sure to include the rewrite:
location ~ \/pma {
rewrite ^/pma(/.*)$ $1 break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://localhost:8081;
}
You'll also want to set the PMA_ABSOLUTE_URI environment variable in your docker-compose.yml:
PMA_ABSOLUTE_URI: https://yourdomain.com/pma/
Provided you're running 4.6.5 or later of the docker phpmyadmin you should be set. To update you can docker pull to pull down the latest. i.e.
docker pull phpmyadmin/phpmyadmin
Upvotes: 32
Reputation: 36763
Just remove the ending backslash of /pma/
:
location /pma {
proxy_pass http://localhost:8081/;
proxy_buffering off;
}
With it the browser treats it as a directory and request for assets accordingly, which is unexpected for PMA.
Upvotes: 4