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

From Leeroopedia


Knowledge Sources misc/python/materialize/mzbuild.py (ResolvedImage.build, ResolvedImage.write_dockerfile)
Domains Build Systems, Containerization, Cross-Compilation, CI/CD
Last Updated 2026-02-08

Overview

Concrete implementation of multi-stage container image construction provided by ResolvedImage.build() in Materialize's mzbuild system, orchestrating pre-image actions, Dockerfile rewriting, and Docker build execution.

Description

ResolvedImage.build() (lines 879-953) is the method that actually builds a Docker image from source. It performs the following steps in sequence:

  1. Clean the build context -- Runs git clean -ffdX on the image's directory to remove all untracked and gitignored files, ensuring a pristine build context.
  1. Execute pre-image actions -- Iterates over the image's pre_images list (e.g., CargoBuild, Copy) and runs each with the pre-prepared batch data from prep.
  1. Assemble build arguments -- Constructs the build_args dictionary combining image-specific build args from mzbuild.yml with system-level args: BUILD_PROFILE, ARCH_GCC, ARCH_GO, and CI_SANITIZER.
  1. Render the Dockerfile -- Calls write_dockerfile() which reads the image's Dockerfile, replaces all MZFROM {name} directives with standard FROM {resolved_spec} lines (using the dependency's fingerprint-tagged spec), and writes the result to a temporary file.
  1. Select build backend -- Attempts to use docker buildx build. If buildx is not installed, falls back to docker build (unless push=True, in which case buildx is required and an error is raised).
  1. Authenticate to GHCR -- If the GITHUB_GHCR_TOKEN environment variable is set, logs into ghcr.io using docker login with the materialize-bot user.
  1. Execute the Docker build -- Runs the assembled command, piping the rendered Dockerfile via stdin (-f -). With buildx, the image is dual-tagged for both Docker Hub (docker.io/{spec}) and GHCR (ghcr.io/materializeinc/{spec}). The --load flag is used for local builds, or --push for remote publishing.

Usage

Use ResolvedImage.build() when:

  • Building an image locally during development -- Call with push=False (default) to build and load the image into the local Docker daemon.
  • As part of the DependencySet.acquire() workflow -- When a pre-built image cannot be pulled from the registry, acquire() falls back to building from source.
  • Never call directly without preparation -- The prep dictionary must be populated by calling DependencySet._prepare_batch() first, which runs PreImage.prepare_batch() for all pre-image action types.

Code Reference

Source Location

File misc/python/materialize/mzbuild.py
build() Lines 879-953
write_dockerfile() Lines 860-877
spec() Lines 851-858

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 write_dockerfile(self) -> IO[bytes]:
        """Render the Dockerfile without mzbuild directives.

        Returns:
            file: A handle to a temporary file containing the adjusted
                Dockerfile.
        """
        ...

    @cache
    def spec(self) -> str:
        """Return the "spec" for the image.

        A spec is the unique identifier for the image given its current
        fingerprint. It is a valid Docker Hub name.
        """
        return self.image.docker_name(tag=f"mzbuild-{self.fingerprint()}")

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, produced by DependencySet._prepare_batch().
push bool If False (default), build and load into the local Docker daemon (--load). If True, build and push to remote registries (--push).
self.image.path Path Directory containing the Dockerfile and mzbuild.yml.
self.image.pre_images list[PreImage] Pre-image actions (e.g., CargoBuild, Copy) to execute before Docker build.
self.image.build_args dict Additional Docker build arguments from mzbuild.yml.
self.image.rd.profile Profile Rust build profile name injected as BUILD_PROFILE build arg.
self.image.rd.arch Arch Target architecture, used for ARCH_GCC, ARCH_GO, and --platform.
self.image.rd.sanitizer Sanitizer Sanitizer mode injected as CI_SANITIZER build arg.
GITHUB_GHCR_TOKEN env var str (optional) If set, used to authenticate to GHCR before building.

Outputs

Output Type Description
Return value None The method returns nothing; it operates via side effects.
Side effect: Docker image Docker daemon / registry A Docker image tagged with self.spec() is either loaded locally (--load) or pushed to registries (--push).
Side effect: git clean Filesystem All untracked and gitignored files in the image directory are removed.
Side effect: pre-image artifacts Filesystem Pre-image actions (e.g., Cargo build) may produce binary artifacts in the build context.

Usage Examples

Building an image locally (via DependencySet):

from pathlib import Path
from materialize.mzbuild import Repository

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

# acquire() tries to pull first, falls back to build()
deps.acquire()

Understanding the internal build flow:

# Step 1: Clean the build context
#   git clean -ffdX /path/to/image/dir

# Step 2: Run pre-image actions
#   e.g., CargoBuild compiles Rust binaries and copies them
#   into the image directory

# Step 3: Assemble build args
#   build_args = {
#       **image.build_args,            # from mzbuild.yml
#       "BUILD_PROFILE": "OPTIMIZED",  # from rd.profile
#       "ARCH_GCC": "x86_64",          # from rd.arch
#       "ARCH_GO": "amd64",            # from rd.arch.go_str()
#       "CI_SANITIZER": "none",        # from rd.sanitizer
#   }

# Step 4: Render Dockerfile (MZFROM -> FROM)
#   MZFROM some-dep  -->  FROM materialize/some-dep:mzbuild-FINGERPRINT

# Step 5: Execute docker buildx build
#   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 \
#     --load

Dual-tagging for Docker Hub and GHCR:

# When using buildx, the image is tagged for both registries:
#   -t docker.io/{spec}
#   -t ghcr.io/materializeinc/{spec}
#
# Where {spec} = "materialize/environmentd:mzbuild-ABCDE..."
# This allows the image to be pulled from either registry.

Related Pages

Implements Principle

Requires Environment

Uses Heuristic

Page Connections

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