Like all build systems, there are dependencies that may be required to build a package. These dependencies often are large and immutable, and can be cached to speed up the build process.
For example, Go has its modules cache, NPM keeps installed packages in node_modules, Maven stores downloaded
packages in its .m2 directory, and so on.
As each build often requires all the same packages, it can be very inefficient to download and install them with each build. To optimize this, melange has an optional build cache feature.
When you run melange build, you can specify a cache directory with the --cache-dir flag. The value you provide here should be a path to a directory on your local filesystem. This local directory will be mounted into the build workspace (e.g. a running container) at the path /var/cache/melange.
This enables you to speed up builds by preloading data into the cache before you run melange build. Depending on the runner you use, you may also be able to persist cache data generated by the build itself for use in subsequent builds (see Cache Persistence by Runner below).
If you're using Melange to build a Go project, and you already have Go set up on your local machine, you can use your Go modules cache as a build cache by running:
melange build --cache-dir "$(go env GOMODCACHE)" ...This will mount your local Go modules cache (usually a path like /Users/<you>/go/pkg/mod) into the build workspace at /var/cache/melange. IMPORTANT: To tell Go where to find this cache, make sure to set the environment variable GOMODCACHE to /var/cache/melange. You can set environment variables in your Melange config here:
environment:
contents:
packages:
# ...
environment:
GOMODCACHE: '/var/cache/melange' # <-- here!Or you can just set the variable as a normal shell command within the runs: pipeline step where you're running Go:
pipeline:
- runs: |
GOMODCACHE="/var/cache/melange"
# ...Now you're all set! If you've already downloaded the Go modules you need for your Go project to your local filesystem, you'll no longer need to wait for Melange to download those Go modules during every build. This can significantly speed up builds!
Note: Whether modifications to the cache during a build persist to your local filesystem depends on which runner you use. See Cache Persistence by Runner for details.
If you're using Melange to build a Python project with uv, you can take advantage of melange's built-in UV cache support to speed up your builds.
Melange automatically sets the UV_CACHE_DIR environment variable to /var/cache/melange/uv by default. This means you can use the --cache-dir flag to mount a local directory that will be used as the UV cache:
melange build --cache-dir /path/to/your/cache ...When using a dedicated UV cache directory on your host, you can mount it directly:
# Create a cache directory for UV
mkdir -p ~/.cache/melange/uv
# Run melange with the cache directory
melange build --cache-dir ~/.cache/melange ...The UV cache will be stored under /var/cache/melange/uv inside the build environment. If you want to customize this path, you can override it in your Melange config:
environment:
environment:
UV_CACHE_DIR: '/var/cache/melange/uv' # This is the defaultOr set it within a pipeline step:
pipeline:
- runs: |
UV_CACHE_DIR="/var/cache/melange/uv"
uv pip install -r requirements.txtThis caching support helps significantly speed up Python builds that use UV by avoiding repeated downloads of packages across builds.
If you're using Melange to build a Python project with the standard pip package manager, you can take advantage of melange's built-in pip cache support to speed up your builds.
Melange automatically sets the PIP_CACHE_DIR environment variable to /var/cache/melange/pip by default. This means you can use the --cache-dir flag to mount a local directory that will be used as the pip cache:
melange build --cache-dir /path/to/your/cache ...When using a dedicated pip cache directory on your host, you can mount it directly:
# Create a cache directory
mkdir -p ~/.cache/melange
# Run melange with the cache directory
melange build --cache-dir ~/.cache/melange ...The pip cache will be stored under /var/cache/melange/pip inside the build environment. If you want to customize this path, you can override it in your Melange config:
environment:
environment:
PIP_CACHE_DIR: '/var/cache/melange/pip' # This is the defaultOr set it within a pipeline step:
pipeline:
- runs: |
PIP_CACHE_DIR="/var/cache/melange/pip"
pip install -r requirements.txtThis caching support helps significantly speed up Python builds by avoiding repeated downloads of packages across builds.
If you're using Melange to build a PHP project with Composer, you can take advantage of melange's built-in Composer cache support to speed up your builds.
Melange automatically sets the COMPOSER_CACHE_DIR environment variable to /var/cache/melange/composer by default. This means you can use the --cache-dir flag to mount a local directory that will be used as the Composer cache:
melange build --cache-dir /path/to/your/cache ...When using a dedicated Composer cache directory on your host, you can mount it directly:
# Create a cache directory
mkdir -p ~/.cache/melange
# Run melange with the cache directory
melange build --cache-dir ~/.cache/melange ...The Composer cache will be stored under /var/cache/melange/composer inside the build environment. If you want to customize this path, you can override it in your Melange config:
environment:
environment:
COMPOSER_CACHE_DIR: '/var/cache/melange/composer' # This is the defaultOr set it within a pipeline step:
pipeline:
- runs: |
COMPOSER_CACHE_DIR="/var/cache/melange/composer"
composer installThis caching support helps significantly speed up PHP builds by avoiding repeated downloads of packages across builds.
If you're using Melange to build a JavaScript/Node.js project with npm, you can take advantage of melange's built-in npm cache support to speed up your builds.
Melange automatically sets the npm_config_cache environment variable to /var/cache/melange/npm by default. This means you can use the --cache-dir flag to mount a local directory that will be used as the npm cache:
melange build --cache-dir /path/to/your/cache ...When using a dedicated npm cache directory on your host, you can mount it directly:
# Create a cache directory
mkdir -p ~/.cache/melange
# Run melange with the cache directory
melange build --cache-dir ~/.cache/melange ...The npm cache will be stored under /var/cache/melange/npm inside the build environment. If you want to customize this path, you can override it in your Melange config:
environment:
environment:
npm_config_cache: '/var/cache/melange/npm' # This is the defaultOr set it within a pipeline step:
pipeline:
- runs: |
npm_config_cache="/var/cache/melange/npm"
npm installThis caching support helps significantly speed up Node.js builds by avoiding repeated downloads of packages across builds.
Maven caching is automatically enabled when using the maven/configure-mirror or maven/pombump pipelines. When a cache directory is mounted at /var/cache/melange, the pipelines automatically symlink ~/.m2/repository to /var/cache/melange/m2repository so that Maven's default local repository is backed by the cache.
To use Maven caching, simply provide a cache directory:
melange build --cache-dir /path/to/my/cache ...No additional configuration is required in your Melange config. The Maven pipelines detect the mounted cache directory and set up the symlink automatically. This is useful for Java projects with many dependencies (e.g., apicurio-registry requires over 1 GB of dependencies).
On subsequent builds, Maven will reuse the downloaded dependencies from the cache, avoiding redundant downloads.
The cache directory mount behavior varies depending on which runner you use:
| Runner | Mount Type | Writes Persist to Host |
|---|---|---|
| Docker | Bind mount (read-write) | Yes |
| Bubblewrap | Bind mount (read-write) | Yes |
| QEMU (default) | 9p (read-only) + overlay | No |
| QEMU (virtiofs) | virtiofs (read-write) | Yes |
Both Docker and Bubblewrap mount the cache directory as a standard read-write bind mount. Any modifications made to /var/cache/melange during the build will directly affect your local filesystem. This allows builds to populate the cache for use in subsequent builds.
By default, QEMU mounts the cache directory using the 9p protocol with a read-only flag. To allow builds to write to the cache, an overlay filesystem is layered on top:
- Lower layer: Read-only 9p mount of your host cache directory
- Upper layer: Temporary writable directory inside the guest
This means builds can read from your pre-populated cache, but any writes during the build go to the overlay's upper directory and are discarded when the build completes. To persist cache writes with QEMU, enable virtiofs (see below).
When using the QEMU runner, the default 9p mount does not persist cache writes to the host. To enable cache persistence (and improve I/O performance), you can use virtiofs instead.
To enable virtiofs for the cache directory, set the QEMU_USE_VIRTIOFS environment variable:
QEMU_USE_VIRTIOFS=1 melange build --runner qemu --cache-dir /path/to/cache ...Requirements:
- The
virtiofsdbinary must be available on the host system (checked at/usr/libexec/virtiofsd,/usr/lib/qemu/virtiofsd, or in$PATH). Alternatively, setQEMU_VIRTIOFS_PATHto a directory containing thevirtiofsdbinary (useful for macOS/brew or non-standard installations). - The host system must support virtiofs (Linux with appropriate kernel support)
When virtiofs is enabled, the cache directory is mounted as a read-write virtiofs share, providing:
- Cache persistence: Writes during the build are saved to your host filesystem
- Better I/O performance: virtiofs offers improved performance compared to 9p
If QEMU_USE_VIRTIOFS=1 is set but virtiofsd is not found, melange will return an error. If the environment variable is not set or set to 0, the default 9p+overlay mount is used and cache writes are not persisted.