Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
9637ab1
[release] bump version 1.19.7
pditommaso May 6, 2025
413d730
Initial pixi support
pditommaso May 16, 2025
7c3da4e
Add singularity file
pditommaso May 18, 2025
97ce38f
Merge branch 'master' into build-template
pditommaso May 25, 2025
072d16b
Merge branch 'master' into build-template
pditommaso Jun 11, 2025
7872178
Merge branch 'master' into build-template
pditommaso Jun 11, 2025
5c9106a
Merge branch 'master' into build-template
pditommaso Jun 16, 2025
7e72e4f
Merge branch 'master' into build-template
pditommaso Aug 5, 2025
d73b56c
Merge branch 'master' into build-template
pditommaso Aug 19, 2025
59c3013
Merge branch 'master' into build-template
munishchouhan Nov 11, 2025
a72f925
Update src/test/groovy/io/seqera/wave/util/ContainerHelperTest.groovy
munishchouhan Nov 11, 2025
115dd65
Comment out includeBuild for libseqera
munishchouhan Nov 11, 2025
c4fde03
Merge branch 'master' into build-template
munishchouhan Dec 1, 2025
b4c7cf3
added wave-api and wave-utils changes
munishchouhan Dec 1, 2025
844b285
Merge branch 'master' into build-template
munishchouhan Dec 1, 2025
5b9c4c4
added docs
munishchouhan Dec 1, 2025
0abb129
added tests
munishchouhan Dec 1, 2025
09afe0c
added PixiOpts.tsp
munishchouhan Dec 1, 2025
24c5807
Merge branch 'master' into build-template
munishchouhan Dec 1, 2025
e113601
added api version
munishchouhan Dec 1, 2025
c7aa021
fixed PixiOpts
munishchouhan Dec 1, 2025
9110f6c
Added singularity for micromamba-v2 and fixed errors and added tests …
munishchouhan Dec 2, 2025
d5f1c7a
Merge branch 'master' into build-template
pditommaso Dec 3, 2025
7ddbf48
Add ADR doc [ci skip]
pditommaso Dec 3, 2025
813a62b
Add more comment [ci skip]
pditommaso Dec 3, 2025
93009e2
Add more comments [ci skip]
pditommaso Dec 3, 2025
3b0fca1
More comments [ci skip]
pditommaso Dec 3, 2025
6a4e454
Add BuildTemplate constants for build template strings
pditommaso Dec 3, 2025
b42d493
Rename withMambaImage to withPixiImage and add micromamba v2 tests
pditommaso Dec 3, 2025
65d3da8
Rename containerFileFromPackages and condaLockFile methods
pditommaso Dec 3, 2025
4c90495
Refactor container file generation into specialized helper classes
pditommaso Dec 3, 2025
3990fbe
Rename refactor
pditommaso Dec 3, 2025
240b880
Remove dead code from DockerHelper
pditommaso Dec 3, 2025
7fc847d
Rename cran templates to cran-installr-v1
pditommaso Dec 3, 2025
c9fb46e
Rename template directories for consistency
pditommaso Dec 3, 2025
468b5ca
Rename template directories and update BuildTemplate constants
pditommaso Dec 3, 2025
ef2f7b5
Refactor ContainerHelper dispatch logic with static imports and impro…
pditommaso Dec 3, 2025
1f2677d
Update default container images and add buildTemplate documentation
pditommaso Dec 3, 2025
18ee886
Fix documentation to match actual implementation
pditommaso Dec 3, 2025
299591c
[release] bump version 1.31.0-B1
pditommaso Dec 3, 2025
6719937
Add buildTemplate to build view and mail notification, refactor Build…
pditommaso Dec 3, 2025
bd24f61
Add BuildTemplate.defaultTemplate helper for package type detection
pditommaso Dec 3, 2025
7f0ac40
[release] bump version 1.31.0-B2
pditommaso Dec 3, 2025
8b6d0fa
[release] Fix BuildStrategyTest to use named parameters with BuildReq…
pditommaso Dec 3, 2025
1283a16
Change build template naming to SCOPE/INSTALLER/VERSION format
pditommaso Dec 5, 2025
7f107db
[release] bump version 1.31.0-B3
pditommaso Dec 5, 2025
0386b4f
fixed pixi singularity build
munishchouhan Dec 5, 2025
dc3b650
fixed micromamba-v2 singularity build
munishchouhan Dec 5, 2025
ab6a6ed
added docs
munishchouhan Dec 5, 2025
f575c78
[release] test 1.31.0-B4
munishchouhan Dec 5, 2025
ce07fa5
fixed test
munishchouhan Dec 5, 2025
3fcafd7
Document tar requirement for Singularity multi-stage builds
pditommaso Dec 10, 2025
f2c3967
[release]
pditommaso Dec 10, 2025
1fd8ced
Merge branch 'master' into build-template
munishchouhan Dec 10, 2025
c1ec20a
Revert version
pditommaso Dec 10, 2025
a03e1cb
Change build template syntax to <scope>/<name>:<version> format
pditommaso Dec 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions adr/20251203-multi-stage-build-templates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
# Multi-Stage Build Templates for Container Provisioning

## Summary

This document describes the implementation of multi-stage build templates in Wave, introducing support for Pixi (`pixi/v1`) and enhanced Micromamba (`micromamba/v2`) templates. These templates produce smaller, optimized container images by separating build-time dependencies from runtime environments.

## Context

Wave's default container builds using Micromamba v1 include the package manager and build tools in the final image. This results in larger images and potential security concerns from unnecessary binaries. Additionally, users requested support for Pixi, a modern and faster package manager from prefix.dev.

## Feature Overview

### What it does
- **Multi-Stage Builds**: Separates package installation (build stage) from runtime (final stage)
- **Pixi Support**: New `pixi/v1` template using the Pixi package manager
- **Enhanced Micromamba**: New `micromamba/v2` template with multi-stage builds
- **Singularity Support**: Both templates support Docker and Singularity formats
- **Lock File Generation**: Produces reproducible builds with `pixi.lock` or `environment.lock`

### How it works

1. User submits container request with `buildTemplate` field
2. Wave routes to appropriate template based on value (`pixi/v1` or `micromamba/v2`)
3. Multi-stage build executes:
- **Stage 1 (build)**: Package manager installs dependencies
- **Stage 2 (final)**: Only the conda environment is copied to minimal base image
4. Final image contains runtime only, no build tools

## Decision Drivers

1. **Image Size**: Need to reduce container image sizes for faster pulls and reduced storage
2. **Modern Tooling**: User demand for Pixi support (faster resolution, better UX)
3. **Reproducibility**: Lock files ensure exact package versions across builds
4. **Security**: Fewer binaries in final image reduces attack surface
5. **Backward Compatibility**: Existing workflows must continue working unchanged

## Technical Decisions

### 1. Template Selection via API Field

**Decision:** Added `buildTemplate` field to `SubmitContainerTokenRequest`

| Value | Template | Package Manager |
|-------|----------|-----------------|
| `null` (default) | micromamba v1 | micromamba (single-stage) |
| `conda/pixi:v1` | pixi v1 | pixi (multi-stage) |
| `conda/micromamba:v2` | micromamba v2 | micromamba (multi-stage) |

**Rationale:**
- Explicit selection avoids ambiguity
- Backward compatible (null = existing behavior)
- Easy to add new templates in future

### 2. Pixi as First-Class Package Manager

**Decision:** Added `PixiOpts` configuration class alongside existing `CondaOpts`

| Option | Default | Description |
|--------|---------|-------------|
| `pixiImage` | `ghcr.io/prefix-dev/pixi:0.59.0-noble` | Build stage image |
| `baseImage` | `ubuntu:24.04` | Final stage base |
| `basePackages` | `conda-forge::procps-ng` | Additional runtime packages |
| `commands` | (empty) | Custom commands |

**Rationale:**
- Pixi has different defaults and behavior than Micromamba
- Separate configuration prevents option confusion
- Allows Pixi-specific features (e.g., shell-hook activation)

### 3. Multi-Stage Build Architecture

**Decision:** Two-stage builds for both `pixi/v1` and `micromamba/v2`

| Stage | Purpose | Contents |
|-------|---------|----------|
| Build | Package installation | Full package manager, build tools, cache |
| Final | Runtime | Conda environment only, shell activation script |

**Rationale:**
- Significant size reduction (build tools excluded)
- Cleaner separation of concerns
- Industry standard practice for production containers

### 4. Environment Activation Strategy

**Decision:** Generate shell-hook script for automatic environment activation

- Pixi: `/shell-hook.sh` generated via `pixi shell-hook`
- Micromamba: Standard `/opt/conda` activation

**Rationale:**
- Ensures environment is active on container start
- No package manager binary needed at runtime
- Works with both interactive and non-interactive shells

### 5. Singularity Multi-Stage Support

**Decision:** Implemented multi-stage Singularity definitions for both templates

**Rationale:**
- HPC environments commonly use Singularity
- Feature parity between Docker and Singularity
- Uses same build logic, different definition syntax

## API Changes

### New Request Fields

| Field | Type | Location | Description |
|-------|------|----------|-------------|
| `buildTemplate` | String | `SubmitContainerTokenRequest` | Template selector |
| `pixiOpts` | Object | `PackagesSpec` | Pixi configuration |

### PackagesSpec Options Support

| Template | `condaOpts` | `pixiOpts` |
|----------|-------------|------------|
| Default (v1) | Yes | No |
| `conda/micromamba:v2` | Yes | No |
| `conda/pixi:v1` | No | Yes |

## Template Comparison

| Aspect | Default (v1) | `conda/micromamba:v2` | `conda/pixi:v1` |
|--------|--------------|----------------------|-----------------|
| Build stages | 1 | 2 | 2 |
| Package manager in final | Yes | No | No |
| Lock file | No | Yes | Yes |
| Base image configurable | Yes | Yes | Yes |
| Singularity support | Yes | Yes | Yes |
| Relative image size | Large | Small | Small |

## Files Changed

| Category | Files |
|----------|-------|
| API Models | `SubmitContainerTokenRequest.java`, `PackagesSpec.java`, `PixiOpts.java` |
| TypeSpec | `ContainerRequest.tsp`, `PackagesSpec.tsp`, `PixiOpts.tsp` |
| Templates | `pixi-v1/*.txt`, `micromamba-v2/singularityfile-*.txt` |
| Helpers | `DockerHelper.java`, `ContainerHelper.groovy` |
| Controller | `ContainerController.groovy` |
| Tests | `*Test.groovy` for all modified components |
| Docs | `api.md` |

## Consequences

### Positive
- Smaller container images (30-50% reduction typical)
- Reproducible builds via lock files
- Modern Pixi package manager available
- Better security posture (fewer binaries)
- Full Singularity support for HPC users

### Negative
- Build time slightly increased (two stages)
- More template files to maintain
- Users must learn new `buildTemplate` API field
- Custom images require `tar` utility (dependency requirement)

### Neutral
- Existing API behavior unchanged when `buildTemplate` not specified
- Both Docker and Singularity supported equally

## Requirements

### Custom Image Dependencies (Singularity Only)

When building **Singularity images** (format `sif`), both `conda/pixi:v1` and `conda/micromamba:v2` templates require the `tar` utility to be present in all custom images:

- **Build stage images** (`pixiImage`, `mambaImage`): Need `tar` to compress the conda/pixi environment
- **Final stage images** (`baseImage`): Need `tar` to extract the compressed environment

**Why is `tar` required for Singularity?**

Singularity's multi-stage build implementation uses `proot` to emulate filesystem operations. Unlike Docker's native `COPY --from=build` directive which can copy directories directly between build stages, Singularity's `%files from build` directive with `proot` cannot reliably copy directory structures. To work around this limitation, the templates:

1. Compress the conda/pixi environment into a tarball (`tar czf`) in the build stage
2. Copy the single tarball file to the final stage
3. Extract the environment (`tar xzf`) in the final stage

**Docker builds are not affected**: Docker multi-stage builds use native `COPY --from=build` which handles directory copying natively without requiring `tar`.

**User Impact**: When providing custom images via `pixiOpts.pixiImage`, `condaOpts.mambaImage`, or `baseImage` for **Singularity builds**, users must ensure `tar` is installed. Most standard base images (Ubuntu, Debian, Alpine, Amazon Linux, etc.) include `tar` by default. However, minimal or distroless images may require explicit installation of the tar package.

**Example failure scenario**: Using a minimal distroless image as `baseImage` for a Singularity build without tar will cause the build to fail during the extraction step with an error like `tar: command not found`.

## References

- [Pixi Documentation](https://pixi.sh/)
- [Micromamba Documentation](https://mamba.readthedocs.io/en/latest/user_guide/micromamba.html)
- [Docker Multi-Stage Builds](https://docs.docker.com/build/building/multi-stage/)

---

**Status:** Implemented
**Date:** 2025-12-03
**Authors:** Wave Team
**Branch:** build-template
3 changes: 3 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@
- Remove unused h2 env [e4422b1e]
- added jdbc binder for prometheus metrics (#840) [7094a366]

1.19.7 - 6 May 2025
- Add K8s trace logs for troubleshooting

1.19.6 - 30 Apr 2025
- Bypass cache repo for custom build repos (#828) [29a93053]

Expand Down
Loading
Loading