Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/chainguard-dev/melange/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through building a real APK package with melange from start to finish. You will generate a signing key, write a build configuration, run the build, and inspect the resulting package files. The example used throughout is GNU Hello — a small, well-known C program that is ideal for demonstrating a complete autoconf-based build pipeline.
1
Install melange
2
Before building anything, you need melange on your machine. The quickest paths are Homebrew (macOS and Linux) and the official container image. See the full Installation guide for all options including go install and building from source.
3
Homebrew
brew install melange
Docker
# Verify the image is accessible
docker run --rm cgr.dev/chainguard/melange version
4
Confirm your installation:
5
melange version
6
Generate a signing key
7
Every APK must be signed before it can be installed by an APK client. melange ships a keygen subcommand that generates an RSA key pair sized at 4096 bits by default.
8
melange keygen
9
The output should look like this:
10
 generating keypair with a 4096 bit prime, please wait...
 wrote private key to melange.rsa
 wrote public key to melange.rsa.pub
11
This creates two files in your working directory:
12
FilePurposemelange.rsaPrivate key — used with --signing-key at build time. Keep this secret.melange.rsa.pubPublic key — distributed alongside your package repository so clients can verify signatures.
13
Do not commit melange.rsa to version control. Add it to your .gitignore before proceeding.
14
You can choose a custom key name by passing it as an argument:
15
melange keygen my-packages.rsa
16
Write the build configuration
17
Create a file called hello.yaml in your working directory with the following content. This is the canonical GNU Hello example from the melange repository — it fetches the upstream tarball, configures it with autoconf, compiles it, installs it, and strips the binary:
18
package:
  name: hello
  version: 2.12
  epoch: 0
  description: "the GNU hello world program"
  copyright:
    - attestation: |
        Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2005,
        2006, 2007, 2008, 2010, 2011, 2013, 2014, 2022 Free Software Foundation,
        Inc.
      license: GPL-3.0-or-later
  dependencies:
    runtime:

environment:
  contents:
    repositories:
      - https://packages.wolfi.dev/os
    keyring:
      - https://packages.wolfi.dev/os/wolfi-signing.rsa.pub
    packages:
      - build-base
      - busybox

pipeline:
  - uses: fetch
    with:
      uri: https://mirrors.ocf.berkeley.edu/gnu/hello/hello-${{package.version}}.tar.gz
      expected-sha256: cf04af86dc085268c5f4470fbae49b18afbc221b78096aab842d934a76bad0ab

  - uses: autoconf/configure

  - uses: autoconf/make

  - uses: autoconf/make-install

  - uses: strip
19
Here is what each section does:
20
  • package — metadata: name, version, epoch (used to force upgrades of same-version packages), description, and SPDX license identifier.
  • environment.contents — APK packages and repository URLs assembled into the build guest. These packages are available during compilation but are not included in the final .apk.
  • pipeline — the ordered list of build steps. Each uses entry refers to a named built-in pipeline. fetch downloads and verifies the source tarball; autoconf/configure, autoconf/make, and autoconf/make-install run the standard GNU build system sequence; strip removes debug symbols to reduce package size.
  • 21
    The ${{package.version}} syntax is a melange substitution variable. It is replaced at build time with the value from package.version. See the substitutions reference for the full list.
    22
    Run the build
    23
    With the configuration and signing key in place, run the build. Pass the --arch flag to build only for your current architecture — otherwise melange will attempt to build for all supported targets.
    24
    Native (melange installed locally)
    melange build hello.yaml \
      --signing-key melange.rsa \
      --arch $(uname -m)
    
    Docker
    docker run --privileged --rm \
      -v "${PWD}":/work \
      cgr.dev/chainguard/melange build hello.yaml \
      --signing-key melange.rsa \
      --arch $(uname -m)
    
    25
    The --privileged flag is required when running inside Docker because melange uses bubblewrap to create the isolated build guest, which requires elevated capabilities. When running melange natively on Linux, bubblewrap is used directly and no container daemon is required. On macOS, Docker or Podman must be available because bubblewrap is Linux-only.
    26
    You will see melange bootstrap the build environment, fetch the source tarball, run each pipeline step, and emit the final package. A successful run ends with output similar to:
    27
    INFO -- packages/x86_64/hello-2.12-r0.apk
    INFO -- packages/x86_64/APKINDEX.tar.gz
    
    28
    Inspect the output
    29
    melange writes all output to the packages/ directory (configurable via --out-dir), organized by architecture:
    30
    packages/
    └── x86_64/
        ├── hello-2.12-r0.apk
        └── APKINDEX.tar.gz
    
    31
  • hello-2.12-r0.apk — the signed APK package file. The filename encodes the package name, version, and epoch (r0).
  • APKINDEX.tar.gz — the signed repository index. APK clients use this file to resolve packages from the repository.
  • 32
    To list the contents of the built package, use the tar command (APKs are gzipped tar archives):
    33
    tar -tzvf packages/x86_64/hello-2.12-r0.apk
    
    34
    To build for all default architectures (omit --arch), melange will produce a subdirectory for each target:
    35
    packages/
    ├── aarch64/
    │   ├── hello-2.12-r0.apk
    │   └── APKINDEX.tar.gz
    └── x86_64/
        ├── hello-2.12-r0.apk
        └── APKINDEX.tar.gz
    
    36
    To use your locally built package in an apko image, point apko’s repository list at the packages/ directory and add the melange.rsa.pub public key to the apko keyring configuration.

    Next steps

    You have built and signed your first APK with melange. From here you can:

    Build file reference

    Explore every field available in a melange YAML configuration, including subpackages, test pipelines, and build options.

    Built-in pipelines

    Browse the full library of reusable pipeline steps for autoconf, CMake, Go, Cargo, Python, and more.

    Command reference

    See all flags and options for melange build, melange keygen, melange lint, melange test, and other subcommands.

    Multi-arch builds

    Learn how melange uses QEMU to build for foreign architectures without cross-compilation.

    Build docs developers (and LLMs) love