Add first-class podman support to vip dev-env - #3039
Closed
abdullah-kasim wants to merge 10 commits into
Closed
Conversation
added 10 commits
September 7, 2026 18:30
…xclusions in the dev-env template
Pins package.json to Automattic/lando-cli commit fcd3119869c7bfa8175e287e37bde66690add9e0 (branch shadow-vipodman-09, draft PR #245), which adds the builder.js support for proxyPublishAddress and proxySocket that the podman proxy config wiring in this branch depends on. The previously pinned SHA (78d382f) predates that fix.
3 tasks
Contributor
Dependency ReviewThe following issues were found:
License Issuespackage.json
OpenSSF Scorecard
Scanned Files
|
|
Contributor
Author
|
Failed experiment on my end, I admit. Looks like adding podman support isn't so simple. |
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.



Summary
Makes podman (machine on macOS, rootless on Linux) a first-class, detected
container engine for
vip dev-env, in both the Node.js and Go runtimes, sothe external
~/dotfiles/podman-dockershim stack is no longer needed.Docker users see no behavior change: every new function is a no-op /
identity function for
engine === 'docker'.Companion fix (separate repo, own draft PR): the two new lando config keys
this branch sets (
proxyPublishAddress,proxySocket) require Lando'slando-proxyplugin to honor them, which the previously pinnedAutomattic/lando-clifork commit did not yet do. That fix now lives atAutomattic/lando-cli#245 (branch
add/podman-proxy-config), and this branch'spackage.json#landois pinnedto that commit.
Defects addressed
Running
vip dev-env create/startunder podman without the dotfiles shimsurfaces a chain of masking defects — fixing the first only reveals the
next. This PR addresses defects A through J:
docker infovspodman infoJSON shape) was never distinguished; every downstream decision assumed Dockersrc/lib/dev-environment/engine.ts,internal/devenv/dockercli/engine.godetectEngine/DetectEngine: parse both JSON shapes into a sharedEngineInfo{engine, serverVersion, socketPath, rootless, composePlugin}; falls back todocker/unknownon any unrecognized shape or exec failure, so unrecognizedinfooutput never regresses a working Docker setupsrc/lib/dev-environment/docker-utils.ts,internal/devenv/dockercligetDockerSocket/its Go mirror add the podman machine socket path (macOS), the XDG rootless socket path (Linux), and apodman machine inspectfallback, appended after the existing Docker candidate paths — Docker's own resolution order is unchangedpodman-compose, not Compose v2engine.ts/Go mirrorcomposeRequirement: no-op ({ok:true}) for Docker; for podman, requires a real standalonedocker-composebinary satisfying>=2.0.0, otherwise refuses with a steered remedy message and a docs link. podman-compose translation is explicitly not supported127.0.0.1; podman machine's user-mode networking needs0.0.0.0to be reachable from the hostengine.ts/Goproxy/spec.goproxyPublishAddress(info)returns0.0.0.0under podman,127.0.0.1under Docker; the proxy's own port-availability scan still probes127.0.0.1regardless of engineengine.ts/Goproxy/spec.goproxySocketMount(info)mounts the real discovered socket path at/var/run/docker.sockinside the proxy container, and setssecurity_opt: [label=disable]only when running podman on an SELinux-enforcing Linux hostengine.ts/Goproxy/preflight.gopodmanPreflightis a pure function overEngineInfo+ injected probe results; under podman, ifnet.ipv4.ip_unprivileged_port_startdoesn't allow port 80, it returns a warning naming the exact remedy command (podman machine ssh -- sudo sysctl -w ...on macOS,sudo sysctl -w ...on Linux). It never runs a probe or mutates state itselfassets/dev-env.lando.template.yml.ejs: aninitOnlyservice's dependents usedservice_started, which podman does not treat the same way Docker Desktop does, causing dependent services to race the init containerinitOnlydependency condition now usesservice_completed_successfully. Real for Docker too — this is a template correctness bug, not podman-specificwordpressinit container'srsync --delete /wp/ /shared/deleted sibling bind-mount targets (config, log, vip-config, wp-content/uploads, app-code dirs) that podman does not recreate at container start, unlike Docker DesktopisRunningcheck false, so build steps start-then-kill each service and the VIP health check's retry logic rescans proxy ports and lands on the wrong portdocker-composeversion requirement rather than a separate code pathdockerBinvia a stockenv.getDockerExecutable()that only recognizes a binary literally nameddocker, so on a podman-only machinedockerBinis empty and every downstream check fails before any of A–I ever runsrc/lib/dev-environment/docker-utils.tsgetDockerBin(): triesdockerfirst (no-op / unchanged for Docker users), falls back topodmanwhen only that's usable; wired intogetLandoConfig()before Lando's own config mergeTesting
npm test(lint, check-types, jest): 92 suites, 980 passed / 1 todo, 0 lint errors.go test ./...: all packages pass (withVIP_PROXYunset — an ambient SOCKS proxy in this environment otherwise breaks unrelated loopback-server tests ininternal/gql,internal/sqlexport,internal/telemetry,internal/wpstream; unrelated to this change).make require-node-vip-bin+make test-parity-unit: parity suite green, including newtestdata/parity/devenv-podman-*.jsonfixtures; existing scenarios unchanged (22 pre-existingexpected_driftentries, none newly added).internal/parityDocker scenarios unmodified.Real-hardware acceptance run (this Mac, podman machine, dotfiles shims unstowed)
With
~/dotfiles/podman-dockergenuinely unstowed (stow -D podman-docker—confirmed no
docker/docker-composebinary onPATHafterward) and a realstandalone
docker-composev2 binary installed via Homebrew:First run (before the
getDockerBinfix below),vip dev-env create --slug=podman-support …failed immediately:Root cause:
getLandoConfig()never setdockerBin, so Lando's own configmerge filled it via the stock (unforked)
env.getDockerExecutable(), whichonly searches for a binary literally named
docker. Fixed bygetDockerBin()insrc/lib/dev-environment/docker-utils.ts: tries adocker-named binary first (Docker users see no behavior change — returnsnull, leaving Lando's own default in place), falls back topodmanwhenonly that's usable, wired into
getLandoConfig()before Lando's own configmerge runs.
Second run, with that fix in place,
docker/podmancorrectly resolvesand
getDockerSocket()correctly discovers the podman socket(
/var/run/docker.sock, a symlink to the podman machine socket, installedby
podman-mac-helper) — butvip dev-env createstill fails, with adifferent error:
Root cause (traced in source): this is Lando's own stock, unforked
daemon.js#getVersions(), invoked fromlando.jsduring bootstrap andassigned directly to
lando.config.versions— it shellspodman info --format jsonsuccessfully, but reads onlydockerData.ServerVersion(Docker's JSON shape) and has no podman-shape awareness, so it silently
returns
engine: ''.validateDockerInstalled()in this PR gates on thatexact
lando.config.versions.enginevalue before it ever reaches thisPR's own podman-aware
detectEngine()— sodetectEngine,composeRequirement,proxyPublishAddress,proxySocketMount, andpodmanPreflight(defects A, C, D, E, F — all merged and unit-tested) areprovably correct in isolation but are currently unreachable from the real
CLI entry point under podman, because a stock-Lando health check upstream
of them fails first.
This is reported rather than patched in this run, since it was found by the
real-hardware verification pass rather than planned work — it needs a
follow-up fix: either make
validateDockerInstalledcall this PR's owndetectEngine()before/instead of trustinglando.config.versions.enginefor the emptiness check, or teach a podman-aware version query into the
Lando bootstrap path itself.
No
podman-support-slugged environment or containers were created byeither run (confirmed via
podman ps -aandvip dev-env list— bothfailures happen before any container/network state is touched). The
machine was restored afterward:
stow podman-dockerwas re-run to restorethe dotfiles shims to their pre-run state.
Related