Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:MaterializeInc Materialize ResolvedImage Build Push

From Leeroopedia


Knowledge Sources misc/python/materialize/mzbuild.py (ResolvedImage.build with push=True), misc/python/materialize/docker.py (image_registry)
Domains Build Systems, Container Registries, Artifact Publishing, CI/CD
Last Updated 2026-02-08

Overview

Concrete implementation of content-addressed container registry publishing provided by ResolvedImage.build(prep, push=True), which builds and pushes Docker images to both Docker Hub and GHCR using fingerprint-based tags.

Description

This implementation documents the publishing pathway of the same ResolvedImage.build() method described in Implementation:MaterializeInc_Materialize_ResolvedImage_Build, but focuses specifically on the behavior when push=True is passed.

When push=True:

  1. Buildx is required -- Unlike local builds that can fall back to docker build, pushing requires docker buildx. If buildx is not found, an error is raised with installation instructions.
  1. Dual-registry tagging -- The image is tagged for both Docker Hub and GHCR simultaneously:
    • docker.io/{image_registry}/{image_name}:mzbuild-{fingerprint}
    • ghcr.io/materializeinc/{image_registry}/{image_name}:mzbuild-{fingerprint}
  1. Atomic build-and-push -- The --push flag is passed to docker buildx build, which builds the image and pushes it to all tagged registries in a single operation. This eliminates the gap between build and push that exists with separate docker build + docker push commands.
  1. GHCR authentication -- If GITHUB_GHCR_TOKEN is set in the environment, the method logs into ghcr.io using docker login with the materialize-bot user before executing the build. The token is passed via stdin to avoid command-line exposure.

The image_registry() function (from misc/python/materialize/docker.py) determines the base registry name, returning "ghcr.io/materializeinc/materialize" when MZ_GHCR is truthy (default in CI) or "materialize" (Docker Hub) otherwise.

Usage

Use ResolvedImage.build(prep, push=True) when:

  • Running the DependencySet.ensure() workflow -- This is the primary caller. It checks which images are not yet published and calls build(prep, push=dep.publish) for each one that needs building.
  • Populating the remote build cache -- After a CI build, push all newly-built images so other jobs and future builds can reuse them.
  • Never for local development -- Use push=False for local builds; push=True is intended for CI environments with registry credentials.

Code Reference

Source Location

File misc/python/materialize/mzbuild.py
build() method Lines 879-953
Push-specific logic Lines 900-906 (buildx requirement), 932-938 (dual-tag + --push), 940-951 (GHCR auth)
image_registry() misc/python/materialize/docker.py, Lines 213-218

Signature

class ResolvedImage:
    def build(self, prep: dict[type[PreImage], Any], push: bool = False) -> None:
        """Build the image from source.

        Requires that the caller has already acquired all dependencies and
        prepared all `PreImage` actions via `PreImage.prepare_batch`.
        """
        ...


def image_registry() -> str:
    """Return the active container registry.

    Returns 'ghcr.io/materializeinc/materialize' when MZ_GHCR is truthy
    (default in CI), or 'materialize' (Docker Hub) otherwise.
    """
    return (
        "ghcr.io/materializeinc/materialize"
        if ui.env_is_truthy("MZ_GHCR", "1")
        else "materialize"
    )

Import

from materialize.mzbuild import ResolvedImage

I/O Contract

Inputs

Parameter Type Description
prep dict[type[PreImage], Any] Pre-computed preparation data for each pre-image action type.
push bool Must be True for publishing. Switches from --load to --push in the Docker command.
GITHUB_GHCR_TOKEN env var str (optional) GitHub Container Registry authentication token. Required for pushing to GHCR.
MZ_GHCR env var str Controls which registry image_registry() returns. Defaults to "1" in CI.
self.spec() str The fully-qualified image name with fingerprint tag (e.g., materialize/environmentd:mzbuild-ABCDE...).

Outputs

Output Type Description
Return value None The method returns nothing; it operates via side effects.
Side effect: Docker Hub push Remote registry Image is pushed to docker.io/{spec}.
Side effect: GHCR push Remote registry Image is pushed to ghcr.io/materializeinc/{spec}.
Side effect: GHCR login Docker daemon If GITHUB_GHCR_TOKEN is set, the daemon is authenticated to ghcr.io.

Usage Examples

Publishing via DependencySet.ensure():

from pathlib import Path
from materialize.mzbuild import Repository

repo = Repository(root=Path("/path/to/materialize"))
deps = repo.resolve_dependencies([repo.images["environmentd"]])

# ensure() checks what is published, then builds + pushes missing images
deps.ensure()

# Internally, for each unpublished image:
#   dep.build(prep, push=dep.publish)
# Where dep.publish is True for images marked "publish: true" in mzbuild.yml

Understanding the push command construction:

# When push=True, the buildx command includes:
#   --push          (instead of --load)
#   -t docker.io/{spec}
#   -t ghcr.io/materializeinc/{spec}
#
# Full command example:
#   docker buildx build --progress=plain -f - \
#     --build-arg=BUILD_PROFILE=OPTIMIZED \
#     --build-arg=ARCH_GCC=x86_64 \
#     --build-arg=ARCH_GO=amd64 \
#     --build-arg=CI_SANITIZER=none \
#     -t docker.io/materialize/environmentd:mzbuild-FINGERPRINT \
#     -t ghcr.io/materializeinc/materialize/environmentd:mzbuild-FINGERPRINT \
#     --platform=linux/amd64 \
#     /path/to/image/dir \
#     --push

GHCR authentication flow:

import os

# The build() method checks for the GHCR token before executing the build
token = os.getenv("GITHUB_GHCR_TOKEN")
if token:
    # Authenticates via stdin to avoid exposing the token in process listings
    # docker login ghcr.io -u materialize-bot --password-stdin
    pass

The ensure() concurrency model:

# DependencySet.ensure() builds images in parallel with dependency awareness:
#
# 1. Check which images are already published (parallel, via ThreadPoolExecutor)
# 2. Prepare batch for all images that need building
# 3. Build each image in a ThreadPoolExecutor:
#    - Wait (with timeout) for all dependency images to finish building
#    - Call build(prep, push=True)
#    - Retry up to 3 times on failure (for publishable images)
#
# This allows independent images to build concurrently while respecting
# the dependency ordering within the DAG.

Related Pages

Implements Principle

Requires Environment

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment