Repository navigation
Conversation
desrosj
force-pushed
the
fix-actions-5.5/fix-docker-compose-v2
branch
from
September 11, 2026 21:25
6e58a0e to
e79ca86
Compare
desrosj
force-pushed
the
fix-actions-5.5/fix-docker-compose-v2
branch
from
September 12, 2026 12:46
e79ca86 to
50a48ca
Compare
`packages/env` shells out to a standalone `docker-compose` binary (Docker
Compose v1) via the `docker-compose` npm package's default export.
GitHub's current runner images no longer ship that binary — only the
`docker compose` v2 subcommand, provided by the `docker` CLI plugin, is
present now. As a result, `wp-env start` (and every other `wp-env`
command) fails immediately with `Error: spawn docker-compose ENOENT`,
which is the root cause of effectively all e2e and PHP-unit-test CI
failures on this branch.
This switches every command module (`clean.js`, `destroy.js`, `logs.js`,
`start.js`, `stop.js`, `wordpress.js`) from the package's default export
to its `v2` export, which shells out to `docker compose` instead of the
removed `docker-compose` binary. `run.js`'s manual `spawn()` call (used
so interactive commands like `bash` work, which the npm package can't
support) is updated the same way: it now spawns `docker` with `compose`
prepended to its argument list instead of spawning `docker-compose`
directly. `cli.js`'s error-handling comments/message are reworded to
match, and its corresponding unit test in `test/cli.js` (which asserted
the exact old wording) is updated to match the new message.
The `v2` export only exists in `docker-compose` npm package versions
`>=0.23.x`; this branch was pinned to `^0.22.2`, so `packages/env/package.json`
and `package-lock.json` are updated to bump the dependency. Unlike a
plain `^0.24.3` bump, this pins the exact `0.24.0` release rather than a
caret range: `docker-compose`'s own dependency on `yaml` changed from
`^1.10.2` to `^2.2.2` starting with `0.24.1` (checked every `0.23.x` and
`0.24.x` patch release's declared `yaml` dependency directly via `npm
view docker-compose@<version> dependencies` — `0.23.7`–`0.24.0` all
depend on `yaml@^1.10.2`, `0.24.1` onward depend on `yaml@^2.2.2`;
`0.23.0`–`0.23.6` have no dependencies at all). `0.24.0` is the newest
release that still resolves to a `yaml@1.x`, and it carries none of the
API changes `0.24.1`–`0.24.3` added (a stray `console.log` removal, `ps`
JSON-format support) that this codebase's own call sites don't use, so
it's a safe, minimal choice rather than a downgrade in practice. This
branch's `.nvmrc` pins Node 12, and `yaml@2.x`'s compiled output uses
optional-chaining (`?.`) syntax that V8 didn't support before Node 14 —
confirmed via a real Node 12 `require('docker-compose').v2` on this
exact pin resolving cleanly, and via a direct search of the installed
`yaml@1.10.3` package for `?.` (as well as its `package.json` declaring
plain `"type": "commonjs"`) turning up nothing, whereas the equivalent
check against `yaml@2.x` does. Avoiding `yaml@2.x` entirely means this
branch's already-limited Node 12 runtime never has to load that syntax
in the first place, and (unlike the `yaml@2.x`-based fix that would
otherwise be needed here) no `test/unit/jest.config.js`
`transformIgnorePatterns` allow-list is required either: `yaml@1.x` is
plain CommonJS, so Jest's unmodified default already loads it.
This is the same fix WordPress/gutenberg landed on trunk as commit
`a0943f2fba4a5df0e5ee051bfc567b7f6f7f1942` ("wp-env: Migrate to Compose
V2 (WordPress#51339)"), adapted to this branch's own file layout, dependency
versions, and Node 12 constraint.
desrosj
force-pushed
the
fix-actions-5.5/fix-docker-compose-v2
branch
from
September 12, 2026 14:22
50a48ca to
561c629
Compare
…vice that talks to the database.
Real CI on this PR (after the Docker Compose v2 fix let `wp-env start`
get this far for the first time) showed `wp-env start` hanging for ~30
retries and then failing at the `wp db check` step with:
```
mariadb-check: Got error: 1045: Access denied for user 'example username'@'172.18.0.5' (using password: YES) when trying to connect
```
The literal, space-containing username is not a real credential anyone
configured — it is the hardcoded placeholder default baked into the
official `wordpress` Docker image's `wp-config-docker.php` template:
```php
define( 'DB_USER', getenv_docker('WORDPRESS_DB_USER', 'example username') );
define( 'DB_PASSWORD', getenv_docker('WORDPRESS_DB_PASSWORD', 'example password') );
```
`getenv_docker()` re-evaluates these environment variables every time
`wp-config.php` is loaded, in whatever process loads it — it does not
bake a value in once and share it. `wp-config.php` is generated once by
the `wordpress`/`tests-wordpress` apache containers and then read from
the same shared volume by `cli`/`tests-cli` (which is what actually
runs `wp db check`/`wp core install`) and by `phpunit` (via the
`phpunit-wp-config.php` copy `sed` produces from it). Each of those
containers evaluates `getenv_docker()` using *its own* environment, so
setting `WORDPRESS_DB_USER`/`WORDPRESS_DB_PASSWORD` only on
`wordpress`/`tests-wordpress` is not enough — confirmed directly with a
local reproduction: doing only that still failed with the identical
error, because `cli`'s own environment (which is what `wp db check`
actually runs in) still had neither variable set.
This branch's `wordpress`/`tests-wordpress`/`cli`/`tests-cli`/`phpunit`
services only ever set `WORDPRESS_DB_NAME` (or nothing at all, for
`cli`/`tests-cli`/`phpunit`) — never `WORDPRESS_DB_USER` or
`WORDPRESS_DB_PASSWORD` — so every one of them falls back to the
placeholder default. The `mysql` service, meanwhile, is configured with
`MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'` and no `MYSQL_USER`/`MYSQL_PASSWORD`
of its own, so the only account that actually exists in the database is
`root` with an empty password — never a match for the placeholder.
This is not a Docker Compose v1-vs-v2 regression: the environment
variables a `docker-compose.yml` `environment:` block passes into a
container work identically under both `docker-compose` and
`docker compose`, and this branch's own `build-docker-compose-config.js`
never set these two variables anywhere, in either case. The bug was
simply unreachable until now, because `wp-env start` always failed
earlier, at the `docker-compose` v1 binary's `ENOENT`.
Setting `WORDPRESS_DB_USER: 'root'` and `WORDPRESS_DB_PASSWORD: ''`
explicitly on every service that ever reads `wp-config.php` (matching
the `mysql` service's actual, empty-password `root` account) makes each
of them connect as a user that genuinely exists, instead of silently
falling back to the Docker image's documentation placeholder.
desrosj
force-pushed
the
fix-actions-5.5/fix-docker-compose-v2
branch
from
September 12, 2026 22:09
6f81608 to
5995207
Compare
Owner
Author
|
Superseded by #313, which applies this same fix as a properly stacked layer on the real |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Migrates
wp-env(packages/env) from Docker Compose v1 (a standalonedocker-composebinary) to Docker Compose v2 (thedocker composesubcommand provided by thedockerCLI plugin), pinning thedocker-composenpm dependency to the exact0.24.0release rather than a^0.24.3-style range.Why?
packages/envshells out to a literaldocker-composebinary via thedocker-composenpm package's default (non-.v2) export, andrun.jsalso spawns that binary directly for interactive commands. GitHub's current runner images no longer ship the standalone Docker Compose v1 binary — only thedocker composev2 subcommand (via thedockerCLI plugin) is present now.As a result,
wp-env start(and every otherwp-envcommand) fails immediately withError: spawn docker-compose ENOENT. This is the root cause of essentially all e2e and PHP-unit-test CI failures on this branch, since every one of those jobs depends onwp-envto stand up a WordPress environment before anything else can run.This branch has no Playwright e2e at all (only Puppeteer, via
end2end-test.yml, confirmed viapackage.json), so there is no separate Noble-runner browser-install issue to also account for here.The
.v2export this fix needs only exists indocker-composenpm package versions>=0.23.x. However, this branch also pins Node 12 (.nvmrc), and everydocker-composerelease from0.24.1onward depends onyaml@^2.2.2, which ships its compiled output using optional chaining (?.) syntax — a syntax V8 didn't support before Node 14. Pulling inyaml@2.xbreakswp-env startitself (and every Puppeteer e2e job that depends on it) withSyntaxError: Unexpected token '.', thrown by plain Node loadingyaml/dist/compose/composer.jsdirectly, independent of and in addition to the Docker Compose migration itself. This was confirmed live on an earlier version of this PR that bumped to^0.24.3(see Verification below for the full before/after).Checking every
0.23.x/0.24.xpatch release's own declared dependency (npm view docker-compose@<version> dependencies) found a clean, exact boundary:0.23.0–0.23.6have no dependencies at all;0.23.7through0.24.0depend onyaml@^1.10.2(plain CommonJS, no optional chaining);0.24.1onward depend onyaml@^2.2.2. Pinning the exact0.24.0release gets the.v2export this fix needs while resolving toyaml@1.xinstead — sidestepping the Node 12 incompatibility entirely, rather than needing a Node bump or a Jest-only workaround that wouldn't actually fix a realwp-env start.How?
This is the same fix WordPress/gutenberg landed on trunk as commit
a0943f2fba4a5df0e5ee051bfc567b7f6f7f1942("wp-env: Migrate to Compose V2", #51339, fixes #51249), adapted to this branch's own file layout, dependency versions, and Node 12 constraint:packages/env/lib/cli.jspackages/env/lib/commands/clean.jsrequire( 'docker-compose' )→{ v2: dockerCompose } = require( 'docker-compose' )packages/env/lib/commands/destroy.jspackages/env/lib/commands/logs.jspackages/env/lib/commands/start.jspackages/env/lib/commands/stop.jspackages/env/lib/wordpress.jspackages/env/lib/commands/run.js'compose'to the manually-built compose argument list, and spawnsdockerinstead ofdocker-composedirectly (this file bypasses the npm package for interactive commands likebash, since the package's underlying implementation always passes-T).packages/env/test/cli.js'Error while running docker-compose command.'wording, to matchcli.js's new message.packages/env/package.jsondocker-composefrom^0.22.2to exactly0.24.0(not a caret range — a range would let a future un-pinned install resolve up into0.24.1+, reintroducingyaml@2.x).package-lock.jsondocker-compose@0.24.0and itsyaml@1.10.3dependency, nested under@wordpress/env's own dependency tree since the version needed conflicts with theyaml@1.7.2already pinned at the top level for unrelated packages.version/resolved/integrityfor both taken directly from the npm registry and cross-checked against a realnpm install docker-compose@0.24.0's own generated lockfile output.No
test/unit/jest.config.jschange is needed:yaml@1.xis plain CommonJS (confirmed via itspackage.json's"type": "commonjs"), so Jest's unmodified default transform handling already loads it — unlikeyaml@2.x, which ships as an ES module and would otherwise need atransformIgnorePatternsallow-list (as landed on sibling branches in this project that couldn't avoid theyaml@2.xbump).Verification performed
An earlier version of this PR bumped
docker-composeto^0.24.3and added ajest.config.jsfix foryaml@2.x's ESM output. Real CI on that version confirmed:JavaScriptjob'sSyntaxError: Unexpected token '.'(from Jest loadingyaml/dist/compose/composer.js) was fixed by thetransformIgnorePatternsallow-list.PHPjob'sInstall WordPressstep (npm run wp-env start) and all fourAdmin(Puppeteer e2e) jobs still failed with the identicalSyntaxError: Unexpected token '.'— this time thrown by plain Node itself (not Jest) loading the same file, atif (prelude[i + 1]?.[0] !== '#'), since this branch's pinned Node 12 predates optional-chaining support. This meant the Docker Compose v2 migration could not actually complete a realwp-env starton this branch as written.After re-pinning to
docker-compose@0.24.0(this PR's current state) and pushing:docker-compose@0.24.0under an actual Node 12.22.12 binary (viafnm install 12) in an isolated scratch directory.require('docker-compose').v2resolves cleanly to an object exposing every method this codebase calls (upAll,down,stop,exec,run, etc.) as real functions. Grepped the resolvedyaml@1.10.3package for?.— zero matches, and itspackage.jsondeclares"type": "commonjs".PHP,Admin - 1throughAdmin - 4, andJavaScriptjob's raw log forSyntaxError/Unexpected token/yamlfound zero matches across all of them — the target bug is gone.Install WordPressactually executes realdocker compose down/up/runinvocations to completion, with both themysqlandwordpresscontainers reportedRunningbydocker composeitself.JavaScriptstill fails on the same pre-existing, already-documentedcaniuse-lite/ignore-browserslist-old-datagap noted in this project's tracking (nothing to do with this fix).PHPand all fourAdminjobs now get past Docker Compose entirely, but hit a new, different, previously-unreached failure: wp-env's own database-wait retry loop times out with a MariaDB authentication error (mariadb-check: Got error: 1045: Access denied for user 'example username'@'...' (using password: YES)) — a genuinely new finding, not yet root-caused, out of scope for this PR (which targets the Docker Compose/yaml/Node-12 issue specifically), and a good candidate for a follow-up task now that CI gets far enough to expose it.Check(Static Analysis) fails for the same pre-existing, unrelatedcheck-local-changesreason already confirmed on this PR's own base branch.package-lock.jsonwas validated as well-formed JSON after editing, and its edited region diffs down to exactly the version/resolved/integrity fields fordocker-composeandyaml— nothing else in the file touched.Use of AI Tools
This PR was created by Claude Code under my supervision. All code should be treated as AI-produced and not yet reviewed by a human until this PR is marked Ready for Review.