Application builds¶
magelift build prepares Magento in the pinned builder image and creates an application image from the result. The source repository must be clean. MageLift writes the final artifact manifest outside the repository.
For a local build, run:
Run from the shop repository, with magelift.yaml and composer.lock committed.
Existing app/etc/config.php is an immutable input; disabled modules stay disabled.
The default community recipe uses Magento Open Source 2.4.9, PHP 8.5 and
nginx-fpm on linux/amd64, including on an ARM workstation. The CLI ships the
existing Docker and PHP build recipes with pinned upstream image digests.
It builds the builder and runtime images on your Docker engine, then builds
the application. BuildKit can reuse its cache. No MageLift source checkout or
MageLift image registry is required. Native ARM runtime qualification remains
NOT_RUN.
The nginx runtime maps Magento's numeric static-version URL prefix to the same prebuilt files under pub/static, including files whose path contains a vendor segment. It serves missing static assets as 404 and keeps script and private-media denials. A root /vendor request stays denied. Updating the bundled runtime recipe requires rebuilding the user's application image through CI; promoting an older digest does not apply the new nginx configuration.
BuildKit temporary bind mounts are created below the user cache so Docker Desktop,
Colima, and other /Users-shared Docker engines can access them. The active Docker
Buildx builder is used by default; set BUILDX_BUILDER when a named builder such as
colima is required.
Push a release candidate¶
Run this command in your CI/CD after authenticating Docker to your registry. MageLift constructs the builder and runtime stages on the runner and publishes the deployable application to your selected repository. Intermediate images do not need to be published. The runtime is built from the bundled recipe in the same BuildKit build as the final application; no MageLift image registry is used.
For ECR, create the application repository and grant CI push/pull permissions.
GHCR, ECR, Artifact Registry and other OCI registries use the same --image
option and Docker's configured credentials. For example,
123456789012.dkr.ecr.us-east-1.amazonaws.com/shop:candidate selects ECR.
Successful publication does not prove that the deployment runtime can pull the
image; configure and test its own durable pull identity separately.
A local magelift build loads images into Docker without publishing them.
Pushed builds also default to linux/amd64. Advanced --builder-image and
--runtime-image overrides must be supplied together. Pushed overrides require
registry digests. Explicit ARM or multiple-platform builds require those
advanced images and remain outside the community alpha qualification.
Pushed builds require an immutable HTTPS provenance URL. Private repositories and detached checkouts are accepted; no local branch or Git author identity is required. Repositories with an SSH origin can pass their HTTPS source URL:
magelift build --push \
--source-url https://github.com/example/shop.git \
--image ghcr.io/example/shop:candidate
The CLI adds the full inspected commit checksum to the provenance URL. It rejects URL credentials and unrelated query parameters so they cannot enter image labels or attestations.
BuildKit publishes an SBOM and SLSA provenance with the image. MageLift then signs the pushed digest. magelift build --push and magelift sign use ambient GitHub Actions OIDC when available. A GitHub job requires id-token: write; missing permission fails with guidance. Explicit token overrides retain priority. Workstation signing can use the current gcloud login and the bootstrapped Magento CI service account. Identity tokens are passed to Cosign only as a file path (never a JWT on argv). CR/LF is stripped first. Advanced automation may still set MAGELIFT_COSIGN_IDENTITY_TOKEN_FILE, MAGELIFT_COSIGN_IDENTITY_TOKEN_ARGV, or --identity-token-file. With no Magelift or gcloud token source, Cosign uses ambient OIDC (GitHub Actions or a one-time browser confirmation). Artifact Registry, ECR, and Binary Authorization signatures are not substitutes. The release workflow pins Cosign 3.1.3 through the verified installer action.
Composer credentials are mounted as a private file during preparation. They are not passed to BuildKit, copied into the image, or written to the artifact manifest.
Before BuildKit creates the application image, MageLift compares the isolated
builder's reported PHP branch, Composer version, and loaded extensions with the
requested build contract. A builder response that does not satisfy the request
stops the build before image creation; the opcache request is satisfied by the
PHP runtime's Zend OPcache module name, which is normalized to the stable
zend_opcache artifact identifier.
Traceability¶
The existing external manifest records the source revision, locked input
hashes, PHP and Composer versions, modules, static-content matrix and final
image digest. Its MageLift version comes from the CLI; development builds use
0.0.0-dev. The build-package version remains independent.
The image carries io.magelift.builder.image and the recipe fingerprint in
io.magelift.recipe.sha256. The manifest records that fingerprint, platform and
pinned upstream bases. Advanced base overrides retain their runtime identity
label. The final digest links these inputs to the external manifest. Repeat builds may have different OCI digests while
retaining equivalent declared inputs and application content.
Preparation hooks¶
Hooks extend the validated preparation DAG with an argument vector. The executable
is limited to Composer or bin/magento; shell strings are not accepted.
build:
hooks:
build.prepare:
phase: build
relationship: before
target: build
command:
executable: composer
arguments: [run-script, prepare]
Hooks are ordered by their target and dependency edges. Retries require
idempotent: true, and each hook has a bounded timeout. YAML hooks are limited to
the validate, build, and package phases; deployment-time hooks are provider
extension concerns until the deployment protocol exposes the same typed contract.
Inspect the recipe¶
The destination must not exist. This exports the versioned files and reports
the recipe SHA256 without invoking Docker, Composer credentials or deployment.
Generated files are diagnostic output; keep configuration in YAML. Source-built
images carry io.magelift.recipe.sha256; their runtime label uses
recipe:sha256:<hash> rather than claiming a separately published runtime digest.
Explicit base-image overrides retain their digest labels.
Optional private registry cache¶
build:
cache:
from: [us-central1-docker.pkg.dev/example/build-cache/shop:amd64-recipe-release]
to: us-central1-docker.pkg.dev/example/build-cache/shop:amd64-recipe-release
mode: max
ignoreExportErrors: false
Cache references are separate from the final image. Scope them by project,
architecture/recipe and trust boundary; use different references and permissions
for untrusted work. Cached layers may contain private source and proprietary
packages. Keep that repository private and apply its own retention policy.
ignoreExportErrors is an explicit opt-in; publication/build errors remain fatal.
A missing cache falls back to a cold build. Registry export retains layers,
including intermediate stages in max mode; it does not promise to restore the
contents of RUN --mount=type=cache directories on an ephemeral runner.
Composer credentials supplied by CI¶
The CI supplies COMPOSER_AUTH as a secret containing a non-empty JSON object.
An absent or invalid value fails without printing its contents. This reference
is available only for build-time Composer credentials; runtime secrets retain
the provider reference contract. The existing cloud secret references remain
available. Never put the credential JSON in YAML or pass it as a build argument.
Patch application¶
By default, declared build.qualityPatches IDs run through the standalone
Quality Patches executable from the production Composer lock, then sorted
m2-hotfixes through the host patch tool with idempotent dry-run checks.
Optional build.cloudPatches: true opts into one upstream ece-patches apply
after composer install. The shop must lock magento/magento-cloud-patches;
declared Quality Patch IDs also require magento/quality-patches in the
production lock. Only YAML-declared Quality Patch IDs control selection;
leftover .magento.env.yaml or ambient environment values are ignored. Cloud-required patches, those IDs,
and existing m2-hotfixes are applied in the single upstream pass; MageLift
does not run a second Quality Patch or host hotfix stage afterward. Upstream
owns applicability and patch databases; this path is not a certified matrix cell.
magelift build prints a scope notice on stderr when cloud patches are enabled.
Hotfix failures¶
Host hotfix application first checks whether a patch is needed or fully applied.
A conflict or partially applied patch stops preparation; review its applicability
against the locked Magento version before adjusting it and retrying. These
checks do not merge conflicting patches or make a whole patch series atomic.
When build.cloudPatches is enabled, hotfix failures surface through the
upstream apply instead of the host patch fallback.