docker icon indicating copy to clipboard operation
docker copied to clipboard

Support request: How do you use the FPM version?

Open hkirsman opened this issue 4 years ago • 33 comments

Not sure how it's supposed to work. Could you give some hints?

hkirsman avatar Apr 09 '20 19:04 hkirsman

The fpm versions are built against the PHP FPM Docker images. You need to provide a reverse proxy to interface with the phpMyAdmin fpm container. Most often I see people using an nginx container for this.

https://www.linode.com/docs/web-servers/nginx/serve-php-php-fpm-and-nginx/ is one resource that isn't specific to Docker, but gives a good introduction to the concepts. https://stackoverflow.com/questions/29905953/how-to-correctly-link-php-fpm-and-nginx-docker-containers and https://www.pascallandau.com/blog/php-php-fpm-and-nginx-on-docker-in-windows-10/ have some content that is more specific to Docker.

Is there a specific part you're having particular trouble with?

However, if you aren't comfortable setting that up, I really recommend using the Apache image instead which contains everything you need in one image. phpmyadmin/phpmyadmin:latest is the tag I'd recommend.

ibennetch avatar Apr 09 '20 19:04 ibennetch

Hello,

I stumbled on this question while trying to achieve this, inside a Kubernetes environment.

The question, docker-style is opened here https://github.com/phpmyadmin/docker/issues/253 I read it, tried almost everything, but it's not 100% applicable. Works with pure docker though.

With k8s, the $document_root can't be mounted inside the nginx container, as it is strictly inside phpmyadmin container (the /var/www/html). So nginx fails to serve the static parts.

PHP code is well served by the FPM, no problem with that, I receive a 200 OK GET /index.php HTTP/1.1" 200 3600 But every other resources end up with a 404 as they are not served by the FPM (not his job), nor by nginx (it doesn't have them locally).

Is there somewhere in the documentation a relevant best practice ? I can't be the only one trying to achieve this: Using the fpm build inside a Kubernetes environment, behind a nginx

Thanks,

lordslair avatar Apr 21 '20 15:04 lordslair

@lordslair this is a good question. To be honest, I have never tried to run the phpMyAdmin container from a k8s environment, so I don't have an immediate answer for you.

ibennetch avatar Apr 21 '20 16:04 ibennetch

Thank you for the answer!

For now I'll probably use the "traditional" Apache version then. Just pulled it, and it works flawlessly with nginx using a proxy_pass

If you ever have other feedbacks or try a deploy on k8s, I'll be gladly interested by a follow-up Thanks again,

lordslair avatar Apr 21 '20 17:04 lordslair

Thanks! I'm glad you found a working solution for your situation and sorry again that I didn't have a good answer right away.

This is something I'd love to be able to improve or offer better documentation for, so I may take you up on that. If you make any more progress on this, please let us know here as well.

Cheers!

ibennetch avatar Apr 21 '20 17:04 ibennetch

Hey, this was possible before and stopped working after #285

The way I did it before: Just define /var/www/html as external volume, and mount that volume also in the nginx container.

This of course now is not working anymore, as the /var/www/html directory is filled with the files inside of the container, and hence when mounting it from outside, we are overriding the directory from inside the container, and then the directory is empty.

I currently don't see another solution than to write a custom entrypoint script and therein copy the contents from /var/www/html directory to a custom directory (e.g. /opt/phpmyadmin), and mount to use that custom directory as a shared volume mount for the nginx container too.

Other suggestions are very welcome. It's a bit sad to see that #285 is breaking existing setups :(

rpasing avatar Apr 24 '20 13:04 rpasing

@rpasing I have an idea, what about having an ENV flag to create symlink to a specific folder at start time ?

williamdes avatar Apr 24 '20 13:04 williamdes

Sorry I'm not quite getting what's wrong here @rpasing. What is it you're trying to do here that isn't working? The Kubernetes environment or anything with fpm?

ibennetch avatar Apr 24 '20 14:04 ibennetch

If we have a good reason to revert #285, we certainly can do that because the only reason we do it is from the suggestion at https://github.com/docker-library/official-images/pull/7288. It seems to be an improvement, but if I missed some cases like these that it breaks then we can find a better solution.

ibennetch avatar Apr 24 '20 14:04 ibennetch

hm?

Previously I had something like this in my docker-compose.yml under a container using the phpmyadmin/phpmyadmin:fpm-alpine image:

volumes:
  - /var/www/phpmyadmin/:/var/www/html/

Before #285 that would result in the PMA files being available on the host in the directory /var/www/phpmyadmin, because the entrypoint-script of the PMA container copied the files into the /var/www/html container after the container started, so after the directory has been mounted.

And then I could have in my nginx docker-compose something like:

volumes:
  - /var/www/phpmyadmin/:/var/www/phpmyadmin/:ro

And in the nginx server definitions I could hence reach the static files of PMA from inside the nginx container.

Now, with the changes from #285, the files inside the PMA container in directory /var/www/html are being placed there at container-buildtime (and not after container-startup), so when I mount a directory there after the container started, it will be empty (because the host-directory is empty, and it is beign mounted inside of the container).

Is it clearer now?

rpasing avatar Apr 24 '20 14:04 rpasing

Ah, yes, thank you. That does make sense now. Sorry it's just my inexperience with docker-compose that makes more difficult some things that should be obvious :-) I appreciate your explanation.

Seems to me like you have a great reason for us to revert #285. I can't think of any other workaround that would be suitable.

ibennetch avatar Apr 24 '20 14:04 ibennetch

Actually, I think we should think about a better solution than to just revert #285. I think so because also with the previous approach there were some problems.

For example were PMA-updates not easily doable, because the host always held a non-empty version of the PMA files, and the entrypoint-script then never actually replaced the files with a newer version. My workaround for that was to clear that directory before each container-startup, so that the directory is empty then and the entrypoint-script placed the new files there...

rpasing avatar Apr 24 '20 14:04 rpasing

As far as I know other PHP-projects just do the extraction of the soure-files in the entrypoint-script, and not in the Dockerfile. So instead of downloading to /usr/src/phpmyadmin in the Dockerfile and copying to /var/www/html in the entrypoint, what about downloading+extracting to /var/www/html in the entrypoint, and don't do it in the Dockerfile?

rpasing avatar Apr 24 '20 14:04 rpasing

Hm, that's an interesting case I hadn't considered. I'll have to look further at some of the options here. I appreciate your suggestions.

ibennetch avatar Apr 24 '20 14:04 ibennetch

As far as I can think through, there would never be a scenario where config.inc.php is placed in /var/www/html/ — it always belongs in /etc/phpmyadmin or as environment variables passed to Docker. Does anyone disagree?

ibennetch avatar Apr 29 '20 13:04 ibennetch

As far as I can think through, there would never be a scenario where config.inc.php is placed in /var/www/html/ — it always belongs in /etc/phpmyadmin or as environment variables passed to Docker. Does anyone disagree?

Hmm, I think you are pointing out the case where the config would not be written in he root that the user choose to be right

williamdes avatar Apr 29 '20 13:04 williamdes

Sorry, I think my question just came from nowhere and I should have explained better.

I'm working through the logic of resolving this, and want to correctly handle any situations with the mounted volume. I think that if there's a new phpMyAdmin version, we should just overwrite what's in /var/www/html/, but had a nagging concern that there could be a scenario where a user puts their config.inc.php there. But I think that's not possible.

ibennetch avatar Apr 29 '20 14:04 ibennetch

Sorry, I think my question just came from nowhere and I should have explained better.

I'm working through the logic of resolving this, and want to correctly handle any situations with the mounted volume. I think that if there's a new phpMyAdmin version, we should just overwrite what's in /var/www/html/, but had a nagging concern that there could be a scenario where a user puts their config.inc.php there. But I think that's not possible.

My idea is:

  • use default folder
  • add an env variable to change the root location
  • add an env variable to fill the root directory with our stored data
  • use the same or add one more to manage the configurations filling process ?

williamdes avatar Apr 29 '20 14:04 williamdes

If you revert #285 you may also want to revert parts of https://github.com/phpmyadmin/docker/pull/286/files#diff-80edf79b0f382a3c6e871ac209ffd6ab to restore the custom user feature. Currently www-data is hardcoded.

J0WI avatar May 06 '20 23:05 J0WI

If you revert #285 you may also want to revert parts of https://github.com/phpmyadmin/docker/pull/286/files#diff-80edf79b0f382a3c6e871ac209ffd6ab to restore the custom user feature. Currently www-data is hardcoded.

Yes, thanks, that's a good suggestion.

ibennetch avatar May 07 '20 14:05 ibennetch

  • use default folder
  • add an env variable to change the root location
  • add an env variable to fill the root directory with our stored data
  • use the same or add one more to manage the configurations filling process ?

This feels quite complex to me, is such a system worthwhile?

ibennetch avatar May 07 '20 14:05 ibennetch

  • use default folder
  • add an env variable to change the root location
  • add an env variable to fill the root directory with our stored data
  • use the same or add one more to manage the configurations filling process ?

This feels quite complex to me, is such a system worthwhile?

Maybe reverting the diff would be easier. Anyway it did not cause us trouble as far as I know

williamdes avatar May 07 '20 14:05 williamdes

The problem with the shared volume is that it's essentially a deployment crutch, and it's inherently fragile.

What I'd suggest instead of a shared volume (which is going to ultimately limit scalability) is a short Dockerfile copying the relevant static files from the phpmyadmin image into a new nginx-based image, which can then be scaled separately within the cluster without having a corresponding phpmyadmin container running on every host; something like:

FROM nginx:1.17
COPY --from=phpmyadmin/phpmyadmin:5.0 /var/lib/www /usr/share/nginx/html

You could even go further by pre-baking the NGINX configuration into this image (thus making deployment even simpler).

If you don't need the scalability/performance of NGINX + FPM, that's the use case of the Apache-based default image (which should also work fine behind NGINX, if multiple applications need to run behind the same external port).

tianon avatar May 07 '20 20:05 tianon

@tianon thanks for sharing your thoughts!

We actually have the same discussion in https://github.com/nextcloud/docker/pull/968. I have some concerns with this variant that the two images may get out of sync.

Would you accept this nginx stub image in the library or how can we distribute it?

Another use case for NGINX + FPM is if you use a shared webserver/proxy and multiple FPM applications. But then prebuild nginx stubs are pretty useless.

J0WI avatar May 07 '20 21:05 J0WI

I think if you've got multiple FPM applications, the easiest way is to leverage Docker's "copy up" functionality (https://docs.docker.com/engine/reference/commandline/service_create/#options-for-named-volumes, default enabled for -v but default disabled for --mount) and --volumes-from on your NGINX instance (which also then creates the appropriate "dependency" relationship), but I think that's significantly more complex to accomplish on something like Kubernetes, and is still very fragile.

The reality here is that FPM is difficult to deploy and use in Docker (it wasn't really designed for Docker, after all -- they expect to run on the same host as whatever consumes their FastCGI socket, which is reasonable from the perspective of when it was written). Adding another variant that pre-bakes the NGINX configuration is a band-aid to this problem, although it's a slightly less fragile one (IMO) than sharing volumes with container image source code in them? Given the number of users we've seen over the years complaining about how to use the Wordpress FPM variants, I imagine you'll probably see a lot of users who used the NGINX variant and are wondering why it doesn't "seem to work" (because it won't execute any PHP scripts by itself).

I guess I'm really coming back to whether there's something wrong with just using Apache and letting one container be your "source of truth" for the phpMyAdmin application? :smile:

(Maybe NGINX could be convinced to make a new official image variant for NGINX Unit? :smile:)

tianon avatar May 07 '20 23:05 tianon

Sorry, I didn't really follow this discussion here anymore. What are the results of your thoughts?

What I read so far ("just use the apache-based phpmyadmin image") is not really satisfying: Of course I can proxy that apache httpd through my "external webserver" (which in this case is nginx), but why should I let a full-blown instance of Apache be running just to serve some small static files, which could get served from the nginx directly if it had access to the files? That sounds very unefficient.

A stupid workaround for me for the time being would to create a "stub container" based on Alpine which just copies the files from the phpmyadmin image (like shown above, but now based on Alpine and not nginx) and write an entrypoint script which copies the copied files into a shared volume mount and exits directly afterwards. As I said, stupid workaround.

From my point of view the phpmyadmin php-fpm image should be able to handle a volume mount as storage for its sourcefiles. And that's my problem, it currently doesn't. All "solutions" to this are just workarounds till now.

rpasing avatar May 09 '20 14:05 rpasing

I found this discussion while looking for information on using fpm images, since instructions from here no longer work. Just wanted to state it clearly because it may not be evident from this thread: as far as I can tell, the change made in #285 makes fpm images completely unusable. Those images require a separate web server to handle static files and without shared directory, paths can't be handled correctly. The change you've made means they're no longer able to work with external server, and of course those images don't provide one on their own (since that's the entire point of having them).

For the time being, people can just resort to use "main" (Apache-based) image, but in my opinion reverting #285 should take priority, as it turned out to be a very breaking change. Discussing better solution can take place afterwards.

hbielenia avatar May 29 '20 10:05 hbielenia

Ah, yes, please revert it. I've just hit exact this problem and commented it already here: https://github.com/phpmyadmin/docker/issues/253#issuecomment-685153896

Apache is no alternative. For the time being I would say I dont use this screwed up phpmyadmin fpm docker image and use my own nginx/fpm docker image and install phpmyadmin from source by my own.

pzystorm avatar Sep 01 '20 22:09 pzystorm

i came to the same conclusion when i tried to use it with haproxy (#327), fpm is not usable.

qeepcologne avatar Feb 14 '22 15:02 qeepcologne

I stumbled here after painful experience of trying to make alpine version work. I was just trying to have "quick" solution for one of our contractor's request to have access to phpmyadmin on already dockerized wordpress installation. The discussion here steered in a direction that I can't really follow, but I think this post fits at least OP question.

My problem was mainly that my background is c#/dotnet + usual linux devops, last I touched php was some 15 or 20 years ago. I had no idea what fpm is and how it differs from normal php hosted via apache module, in my head I just assumed it's some nickname for phpmyadmin version itself, like those ubuntu release names. Certainly nothing to worry about. I was just trained from previous experience with docker that alpine version is that one to get, unless I have special needs, and fpm was the only alpine version available, so... why not?

Docker hub description doesn't hint at any pitfalls either - just use the image and it will listen on guest port 80, easy. Only the usual caveats of alpine distribution - different libc etc - something image builder should worry about, not user of that image. Even error messages I get from links or curl on host are very similar, unless I pay close attention ("connection timed out" vs. "connection reset by peer". Which is what pointed me at the right direction when I finally did notice it).

tl;dr: Few words on dockerhub that mention current state of alpine-fpm and that it cannot serve http traffic directly without external fastcgi proxy would have been very helpful.

huancz avatar Apr 11 '22 19:04 huancz