zlayer-builder 0.10.61

Dockerfile parsing and buildah-based container image building
Documentation

zlayer-builder

Dockerfile parsing, ZImagefile support, pipeline orchestration, and buildah-based container image building.

Installation

Add to your Cargo.toml:

[dependencies]
zlayer-builder = "0.8"

Overview

zlayer-builder provides:

  • High-level ImageBuilder API for single image builds
  • PipelineExecutor for multi-image builds with dependency ordering
  • Low-level Dockerfile/ZImagefile parsing and buildah command generation

Build Sources

The builder accepts three kinds of build input (checked in this order):

  1. Runtime template -- specify a runtime like node22 or rust and the builder generates a production-optimized Dockerfile automatically.
  2. ZImagefile -- a YAML-based alternative to Dockerfiles (see below).
  3. Dockerfile -- standard Dockerfile syntax with full multi-stage support.

Modules

Module Description
builder High-level ImageBuilder API for single images
pipeline Multi-image build orchestration with wave-based execution
dockerfile Dockerfile parsing, types, and variable expansion
zimage ZImagefile YAML parsing and Dockerfile conversion
buildah Buildah command generation and execution
templates Runtime templates for common dev environments
tui Terminal UI for build progress
error Error types

ImageBuilder API

Build a single image from Dockerfile, ZImagefile, or runtime template:

use zlayer_builder::ImageBuilder;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let image = ImageBuilder::new("./my-app").await?
        .tag("myapp:latest")
        .build()
        .await?;

    println!("Built image: {}", image.image_id);
    Ok(())
}

With ZImagefile

use zlayer_builder::ImageBuilder;

async fn example() -> Result<(), zlayer_builder::BuildError> {
    let image = ImageBuilder::new("./my-project").await?
        .zimagefile("./my-project/ZImagefile")
        .tag("myapp:latest")
        .build()
        .await?;
    Ok(())
}

With Runtime Template

use zlayer_builder::ImageBuilder;

async fn example() -> Result<(), zlayer_builder::BuildError> {
    let image = ImageBuilder::new("./my-node-app").await?
        .runtime("node22")
        .tag("myapp:latest")
        .build()
        .await?;
    Ok(())
}

Pipeline API

Build multiple images with dependency ordering:

use zlayer_builder::pipeline::{PipelineExecutor, parse_pipeline};
use zlayer_builder::BuildahExecutor;
use std::path::PathBuf;

async fn example() -> Result<(), zlayer_builder::BuildError> {
    let yaml = std::fs::read_to_string("ZPipeline.yaml")?;
    let pipeline = parse_pipeline(&yaml)?;

    let executor = BuildahExecutor::new_async().await?;
    let result = PipelineExecutor::new(pipeline, PathBuf::from("."), executor)
        .fail_fast(true)
        .run()
        .await?;

    println!("Built {} images in {}ms", result.succeeded.len(), result.total_time_ms);
    Ok(())
}

Wave-Based Execution

The pipeline executor resolves dependencies into "waves":

  • Wave 0: Images with no dependencies (run in parallel)
  • Wave 1: Images depending only on Wave 0 images
  • Wave N: Images depending only on earlier waves

ZImagefile Format

YAML-based alternative to Dockerfiles with four build modes:

Mode Top-level key Description
Runtime template runtime Shorthand like runtime: node22
Single-stage base + steps One base image with ordered build steps
Multi-stage stages Named stages (last stage is output)
WASM wasm WebAssembly component builds

Single-Stage Example

base: "alpine:3.19"
steps:
  - run: "apk add --no-cache curl"
  - copy: "app.sh"
    to: "/usr/local/bin/app.sh"
    chmod: "755"
  - workdir: "/app"
env:
  NODE_ENV: production
expose: 8080
cmd: ["./app.sh"]

Multi-Stage Example

stages:
  builder:
    base: "rust:1.90-bookworm"
    workdir: "/src"
    steps:
      - copy: "."
        to: "/src"
      - run: "cargo build --release"
        cache:
          - target: /usr/local/cargo/registry
            id: cargo-registry
            sharing: shared
  runtime:
    base: "debian:bookworm-slim"
    steps:
      - copy: "target/release/myapp"
        from: builder
        to: "/usr/local/bin/myapp"
        chmod: "755"
    cmd: ["/usr/local/bin/myapp"]

expose: 8080

Step Types

Step Description
run Execute a shell command
copy Copy files from context or previous stage
add Add files with URL/archive support
env Set environment variables
workdir Change working directory
user Set the user

Copy/Add Fields

Field Description
copy / add Source file(s) - string or list
to Destination path
from Source stage name (multi-stage only)
owner Owner (user:group)
chmod File permissions (e.g., "755")

Cache Mounts

- run: "npm ci"
  cache:
    - target: /root/.npm
      id: npm-cache
      sharing: shared
      readonly: false

ZPipeline Format

Multi-image build pipeline with dependency ordering:

version: "1"

vars:
  VERSION: "1.0.0"
  REGISTRY: "ghcr.io/myorg"

defaults:
  format: oci
  build_args:
    RUST_VERSION: "1.90"

images:
  base:
    file: images/Dockerfile.base
    tags:
      - "${REGISTRY}/base:${VERSION}"

  app:
    file: images/ZImagefile.app
    depends_on: [base]
    tags:
      - "${REGISTRY}/app:${VERSION}"

push:
  after_all: true

Pipeline Fields

Field Description
version Pipeline format version ("1")
vars Variables for ${VAR} substitution in tags
defaults Default settings for all images
images Named images to build (order preserved)
push.after_all Push all images after successful builds

Image Fields

Field Required Description
file Yes Path to Dockerfile or ZImagefile
context No Build context directory (default: ".")
tags No Image tags with variable substitution
depends_on No Images that must build first
build_args No Build arguments (merged with defaults)
no_cache No Skip cache for this image
format No Output format: "oci" or "docker"

License

MIT - See LICENSE for details.