Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a combined php-fpm-nginx image #102

Merged
merged 14 commits into from
Jul 7, 2023
Merged

Add a combined php-fpm-nginx image #102

merged 14 commits into from
Jul 7, 2023

Conversation

deviantintegral
Copy link
Contributor

This PR adds support to build a single image that contains php-fpm and nginx.

The main advantage as compared to apache + mod_php is that this mirrors what Pantheon does for hosting. As well, while ddev supports apache as the web server, it defaults to nginx with php-fpm.

When I build this locally, I get the following image tags:

tugboatqa/php-fpm-nginx                                                 8.2.5-fpm-buster                  da523af7b96b   3 minutes ago       564MB
tugboatqa/php-fpm-nginx                                                 8.1.18-fpm-buster                 d07c9669284a   3 minutes ago       563MB
tugboatqa/php-fpm-nginx                                                 8.1.18-fpm-bullseye               9cf094317a20   3 minutes ago       614MB
tugboatqa/php-fpm-nginx                                                 8.0.28-fpm-bullseye               dcec48c190a6   3 minutes ago       610MB
tugboatqa/php-fpm-nginx                                                 8.0.28-fpm-buster                 36f58df88aaf   3 minutes ago       559MB
tugboatqa/php-fpm-nginx                                                 8.2.5-fpm-bullseye                b003e269c2c8   3 minutes ago       615MB

To test, I ran docker run --rm --name nginx -p 80:80 tugboatqa/php-fpm-nginx:8.2.5-fpm-bullseye, and then browsed to http://localhost:

image

It's not 1-1 with tugboat given I'm building arm images, but it should be pretty close.

I'm unsure how to test this on a full tugboat project. I'd like to see this work in a full Drupal site, certainly before we expose it in the Tugboat docs. Does it need to be merged first? I guess I'd need to force an amd64 build and push that if I tried to push an image before the PR is merged.

Copy link
Contributor

@q0rban q0rban left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff! This is quite an undertaking. Many folks will be using this, I foresee! Just some questions in here.

Makefile Outdated
@@ -1,15 +1,17 @@
ALL = $(shell ls services | grep -v -e elasticsearch- -e php- -e percona) elasticsearch php
ALL = $(shell ls services | grep -v -e elasticsearch- -e php- -e percona) elasticsearch php php-fpm-nginx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we renamed the directory to nginx-php-fpm I think we could avoid any modifications to the makefile. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing you preferred php at the beginning because the tags will follow php? Not sure how important that is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's it exactly. But I'm open either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one slightly odd thing about the tags is that they also have fpm in them, so to get 8.2.x of php, you need to use tugboatqa/php-fpm-nginx:8.2-fpm, instead of tugboatqa/php-fpm-nginx:8.2. I suppose we could modify the getTags function to also do the filtering, and then strip the fpm from the tag.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this some more, what if we did something like how the apache tags work and add a -nginx suffix: php:8.2-fpm-nginx

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that, because it also follows the variant pattern other images use, such as node:18-alpine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this some more, what if we did something like how the apache tags work and add a -nginx suffix: php:8.2-fpm-nginx

I investigated this, and it would take a refactor of our scripts to accomplish. So I went instead with the approach in #112

@@ -0,0 +1,11 @@
# Override getTags() to always point to the php image, not an invalid
# php-fpm-nginx image.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following this. I'm guessing that NAME can't be specified in this file itself or that creates other issues? But I don't know what those issues are by this comment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@deviantintegral can you weigh in on this and potentially update your comment here with the reasoning for the approach in this manifest?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember right, the issue was that it would try to build from a base image called php-fpm-nginx. The existing scripts assume that the directory name in services/<service> match the upstream image name. There is no docker hub image called php-fpm-nginx so this was failing out.

Am I right this is needed? If there's a better way that's fine by me.

Copy link
Contributor

@q0rban q0rban left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't working as I expect. When I cd $DOCROOT and then modify the files there, I do not see those changes when curling http://127.0.0.1. Can we set up a time to pair program on this @deviantintegral ?

mv /root/tugboat.ini /usr/local/etc/php/conf.d/tugboat.ini && \
mv ${DOCROOT} ${DOCROOT}.original && \
ln -s ${DOCROOT}.original ${DOCROOT} && \
mkdir -p /var/lib/tugboat/web && \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause conflicts when the repository is checked out to /var/lib/tugboat. What are you trying to achieve?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably a drupalism sneaking into this work. I think what this means is that we'd need to make the docroot dynamic somehow in the nginx config?

@deviantintegral
Copy link
Contributor Author

@q0rban re multiple RUN statements, it only matters if future statements modify or delete files from previous statements. If each RUN statement is additive to the previous layers, then there's actually effeciency gains to be had because:

  1. More effective caching of layers. This speeds up builds and local testing in particular.
  2. pulls can get multiple layers in parallel.

https://stackoverflow.com/questions/39223249/multiple-run-vs-single-chained-run-in-dockerfile-which-is-better

@q0rban
Copy link
Contributor

q0rban commented Jul 4, 2023

@q0rban re multiple RUN statements, it only matters if future statements modify or delete files from previous statements. If each RUN statement is additive to the previous layers, then there's actually effeciency gains to be had because:

  1. More effective caching of layers. This speeds up builds and local testing in particular.
  2. pulls can get multiple layers in parallel.

https://stackoverflow.com/questions/39223249/multiple-run-vs-single-chained-run-in-dockerfile-which-is-better

IIRC, I believe the reason we stick to a single run is to intentionally reduce the number of layers, as having more layers limits how many layers Tugboat can then create, since Docker (I think?) imposes a hard limit.

@deviantintegral
Copy link
Contributor Author

Ah! Makes sense. It sounds like that limit may now be a tunable: docker/docs#8230

I wonder if we should eventually either squash all tugboat images as a final step (since we can't control how many layers upstream images use), or see about increasing that tunable.

I also found this experimental option via https://stackoverflow.com/questions/22713551/how-to-flatten-a-docker-image: https://docs.docker.com/engine/reference/commandline/build/#squash

While squashing layers may produce smaller images, it may have a negative impact on performance, as a single layer takes longer to extract, and downloading a single layer cannot be parallelized.

@q0rban
Copy link
Contributor

q0rban commented Jul 4, 2023

Ooooo, neat! Good finds @deviantintegral

@q0rban q0rban merged commit 77a7265 into main Jul 7, 2023
@q0rban q0rban deleted the php-fpm-nginx branch July 7, 2023 11:59
@apotek
Copy link
Contributor

apotek commented Jul 12, 2023

  1. Thank you @deviantintegral @justafish @q0rban for this work that I have been wanting to help with but never found much time to get at.
  2. But I figured testing and maybe contributing some docs counts too?
  3. Just reporting back that changing my drupal service to use nginx rather than apache:
 services:
   drupal:
-    image: chromatichq/php-apache-node:8.1
+    image: tugboatqa/php-nginx:8.1

yields a hung build when built as its own base preview:

2023-07-12T20:17:23.301Z - Building preview: 64af0a5365d7012a0bd345f4 (pr627)

25 minutes pass before

2023-07-12T20:43:17.433Z - Image Not Found (Tugboat Error 1025): tugboatqa/php-nginx:8.1

@apotek
Copy link
Contributor

apotek commented Jul 13, 2023

2023-07-12T20:43:17.433Z - Image Not Found (Tugboat Error 1025): tugboatqa/php-nginx:8.1

@q0rban I am looking at docker hub now and it looks like there are no tags available for specifying the php version. There are tags for (obviously) nginx versions as well as stable and latest, and also perl versions! But nothing for php.

I'm going to re-test without any tags at all (thereby using latest), but I can also maybe create a merge request where I create some php-version tagged images and contribute those. Would you like that or is that something that is better handled in-house?

@apotek
Copy link
Contributor

apotek commented Jul 13, 2023

Update: Even with simply using

services:
  drupal:
    image: tugboatqa/php-nginx

with no tags at all, I get the same result: Hung builds unable to find the image.

Should I best create a separate issue rather than tack all this feedback into a completed merge request?

@q0rban
Copy link
Contributor

q0rban commented Jul 16, 2023

Hi @apotek ! Apologies for the confusion here, as we don't have the tags documented on docs.tugboatqa.com yet while we are still testing this. But the tags all follow the official PHP image with fpm, i.e. 8.1-fpm if you want php 8.1.

You can view all the tags here for now: https://hub.docker.com/r/tugboatqa/php-nginx/tags.
They are also published here: https://github.com/TugboatQA/dockerfiles/blob/main/php-nginx/TAGS.md

Once we have this tested, we will add more details to docs.tugboatqa.com with how to use the image.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants