docker-library / wordpress

Docker Official Image packaging for WordPress
https://wordpress.org/
GNU General Public License v2.0
1.79k stars 1.07k forks source link

Add initial "NGINX Unit" based image #875

Open tianon opened 10 months ago

tianon commented 10 months ago

The Unit configuration I've included here is based on the example provided by the Unit documentation (https://unit.nginx.org/howto/wordpress/), although I did spend time understanding it before blindly trusting it. 😄

The biggest 😬 here (IMO) is that WordPress itself does not know about Unit yet, so the permalink handling is a bit off -- I've added a hack in wp-config-docker.php (specifically in the Unit images only) which works around it by teaching WordPress that Unit is effectively NGINX (which does work and is accurate enough for what WordPress needs), but that should probably be an issue or PR to the WordPress community instead.

(FYI @thresheek - maybe you have more context or know someone who does about WordPress recognizing Unit natively and not injecting /index.php into permalinks when it's the server software? :eyes:)

tianon commented 10 months ago
Diff: ```diff $ diff -u <(bashbrew cat wordpress) <(bashbrew cat <(./generate-stackbrew-library.sh)) --- /dev/fd/63 2024-01-12 09:16:41.475066580 -0800 +++ /dev/fd/62 2024-01-12 09:16:41.479066614 -0800 @@ -3,47 +3,52 @@ Tags: 6.4.2-php8.1-apache, 6.4-php8.1-apache, 6-php8.1-apache, php8.1-apache, 6.4.2-php8.1, 6.4-php8.1, 6-php8.1, php8.1 Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, mips64le, ppc64le, s390x -GitCommit: ac65dab91d64f611e4fa89b5e92903e163d24572 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e Directory: latest/php8.1/apache Tags: 6.4.2-php8.1-fpm, 6.4-php8.1-fpm, 6-php8.1-fpm, php8.1-fpm Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, mips64le, ppc64le, s390x -GitCommit: ac65dab91d64f611e4fa89b5e92903e163d24572 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e Directory: latest/php8.1/fpm Tags: 6.4.2-php8.1-fpm-alpine, 6.4-php8.1-fpm-alpine, 6-php8.1-fpm-alpine, php8.1-fpm-alpine Architectures: amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x -GitCommit: ac65dab91d64f611e4fa89b5e92903e163d24572 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e Directory: latest/php8.1/fpm-alpine Tags: 6.4.2-apache, 6.4-apache, 6-apache, apache, 6.4.2, 6.4, 6, latest, 6.4.2-php8.2-apache, 6.4-php8.2-apache, 6-php8.2-apache, php8.2-apache, 6.4.2-php8.2, 6.4-php8.2, 6-php8.2, php8.2 Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, mips64le, ppc64le, s390x -GitCommit: ac65dab91d64f611e4fa89b5e92903e163d24572 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e Directory: latest/php8.2/apache Tags: 6.4.2-fpm, 6.4-fpm, 6-fpm, fpm, 6.4.2-php8.2-fpm, 6.4-php8.2-fpm, 6-php8.2-fpm, php8.2-fpm Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, mips64le, ppc64le, s390x -GitCommit: ac65dab91d64f611e4fa89b5e92903e163d24572 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e Directory: latest/php8.2/fpm Tags: 6.4.2-fpm-alpine, 6.4-fpm-alpine, 6-fpm-alpine, fpm-alpine, 6.4.2-php8.2-fpm-alpine, 6.4-php8.2-fpm-alpine, 6-php8.2-fpm-alpine, php8.2-fpm-alpine Architectures: amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x -GitCommit: ac65dab91d64f611e4fa89b5e92903e163d24572 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e Directory: latest/php8.2/fpm-alpine +Tags: 6.4.2-unit, 6.4-unit, 6-unit, unit, 6.4.2-php8.2-unit, 6.4-php8.2-unit, 6-php8.2-unit, php8.2-unit +Architectures: amd64, arm64v8 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e +Directory: latest/php8.2/unit + Tags: 6.4.2-php8.3-apache, 6.4-php8.3-apache, 6-php8.3-apache, php8.3-apache, 6.4.2-php8.3, 6.4-php8.3, 6-php8.3, php8.3 Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, mips64le, ppc64le, s390x -GitCommit: ac65dab91d64f611e4fa89b5e92903e163d24572 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e Directory: latest/php8.3/apache Tags: 6.4.2-php8.3-fpm, 6.4-php8.3-fpm, 6-php8.3-fpm, php8.3-fpm Architectures: amd64, arm32v5, arm32v7, arm64v8, i386, mips64le, ppc64le, s390x -GitCommit: ac65dab91d64f611e4fa89b5e92903e163d24572 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e Directory: latest/php8.3/fpm Tags: 6.4.2-php8.3-fpm-alpine, 6.4-php8.3-fpm-alpine, 6-php8.3-fpm-alpine, php8.3-fpm-alpine Architectures: amd64, arm32v6, arm32v7, arm64v8, i386, ppc64le, s390x -GitCommit: ac65dab91d64f611e4fa89b5e92903e163d24572 +GitCommit: 3610d02f059743d924bcda64dcf0ffe839bd904e Directory: latest/php8.3/fpm-alpine Tags: cli-2.9.0-php8.1, cli-2.9-php8.1, cli-2-php8.1, cli-php8.1 ```
tianon commented 10 months ago

What I think we need to resolve in order to merge this:

  1. a new test to make sure it works correctly (and continues to do so)

  2. figure out what to do about the $is_nginx hack I added in wp-config -- that's not a real long-term solution and if we want to merge this, we should have a conversation with the WordPress community first (or find where one has already happened and implement any more official workarounds than my personal hack)

tianon commented 10 months ago

For 1., I guess that's really adapting the existing apache test to be slightly more generic and assigning it to both variants.

thresheek commented 10 months ago

That's pretty cool @tianon! Paging @javorszky for assistance - I believe they have been involved with Unit/Wordpress integration lately on our team.

javorszky commented 10 months ago

@tianon hello! I'll be on this on Monday morning GMT timezone :) I'm super excited about this!

tianon commented 10 months ago

Here's the simplified version of my current hack (for you to review Monday :heart:), since this PR probably isn't the easiest thing in the world to read. :joy:

I'm essentially injecting this at the end of wp-config.php (because it includes wp-settings.php which includes vars.php which is what sets $is_nginx, so if I put it at the end, I can supplement that value with additional detection without patching WordPress itself):

// ...

/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';

// WordPress does not support NGINX Unit (yet), so we have to do a little hackery to let it know that Unit supports nice permalinks (and prevent it from insisting on injecting "/index.php" in all the permalink options) -- the simplest way is teaching it to recognize Unit as if it were NGINX (which is only semi-true, but true enough for these purposes)
$is_nginx = $is_nginx || str_starts_with($_SERVER["SERVER_SOFTWARE"], "Unit/");
// see also https://github.com/WordPress/WordPress/blob/39f7f558d91afdd2f3afc7f3b049a6a800cd3f80/wp-includes/vars.php#L127

More useful backlinks (ie, how I ended up at the conclusion I needed to patch $is_nginx):

I guess a more "upstream-friendly" hack/workaround would be implementing a proper got_url_rewrite filter, but I'm not sure whether I can inject one of those just via wp-config.php or whether that'd have to be a proper plugin (which also isn't a bad idea for non-Docker users which we could recommend users of this image install instead of my hacks). Of course, I still think the ideal solution is probably fixes in WordPress itself to handle this case correctly, but I don't know whether that's already been attempted or whether there's any upstream appetite for that. :sweat_smile:

javorszky commented 10 months ago

Neat, I had some time to look into this. From what I understand this repository is responsible for generating the individual Dockerfiles for WordPress at the different tags.

There are three immediate unit-specific observations:

For upstream work that we need the WordPress folks, I think we need to add two things:

  1. a way for WP to detect that it's running Unit, much like it recognised Nginx and Apache, and
  2. a way for WordPress to reconfigure unit for multisite with the included multisite config file, once 1041 is solved and a unit release contains that one
    • this one won't matter if unit was started without the --control flag
javorszky commented 8 months ago

Hey @tianon,

Small update on where things are on our side:

This PR is an active item in our planning and we keep an eye on it 🙂