Skip to content

RFC: Rust launcher implementation#338

Open
hone wants to merge 5 commits into
buildpacks:mainfrom
hone:launcher-rs
Open

RFC: Rust launcher implementation#338
hone wants to merge 5 commits into
buildpacks:mainfrom
hone:launcher-rs

Conversation

@hone

@hone hone commented Jun 11, 2026

Copy link
Copy Markdown
Member

@buildpack-bot

Copy link
Copy Markdown
Member

Maintainers,

As you review this RFC please queue up issues to be created using the following commands:

/queue-issue <repo> "<title>" [labels]...
/unqueue-issue <uid>

Issues

(none)

Comment thread text/0000-rust-launcher-implementation.md Outdated
Comment thread text/0000-rust-launcher-implementation.md Outdated
Comment thread text/0000-rust-launcher-implementation.md Outdated
Comment thread text/0000-rust-launcher-implementation.md Outdated
@Malax

Malax commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

FWIW, this is very exciting to me. :)

The `launcher` is a critical runtime level component so it's important we ensure stability and verify parity. In order to achieve this there will be a phased rollout:
1. Smoke Testing - The Rust implementation will run alongside the go one in the `lifecycle` acceptance tests so any drifts can be caught ahead of time.
1. Deprecation Period - Once we deem the Rust binary is mature and can be a drop in replacement, we will deprecate the Go binary.
1. Dual Distribution - We will ship both the Go and Rust binaries within `buildpacksio/lifecycle` images simultaneously for this time period also during the testing period. A ~700 KB is a minimal size bump.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a world in which we bump version numbers and leave the go binary behind with no dual shipping?

Builder authors and Platforms are in charge of lifecycle version already depending on the mode (trusted/untrusted).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leave the go binary behind with no dual shipping

You mean that we never dual ship and that in version X the Rust launcher is the launcher?

If so, I guess the intent here is to be able to test the Rust launcher in production without having to resort to weird custom versions/nightlies for the price of ~700KB for everyone - even if they are not interested in the new launcher.

Personally, dual shipping for at least one version (range) seems like a practical approach to make sure we're ready to make the move to the Rust launcher and have non-CNB maintainers be able to test this in their setup without much hassle compared to using a nightly version or something.

Of course, in either case we need to vet this new launcher thoroughly before, but with the dual shipping we can get some real world testing in earlier.

I think there is a world were we don't double ship. A decision/tradeoff has to be made here.

@hone

hone commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

From CNB WG:

  • Update motivation to include smaller dependency surface area vs. Go. The rest of lifecycle is a "dev tool" which pulls in heavy dependencies like moby. Splitting this makes the SBOM smaller.
  • What if we don't do dual distribution and just ship it as part of a 1.0 style release after we feel confident
  • add versioning
  • @jabrown85 to add more "outside in" launcher acceptance tests to ensure byte for byte compatible output messages/errors.
  • Port more comprehensive test suite from https://github/jabrown85/launcher-rs.

hone and others added 4 commits June 11, 2026 09:55
Co-authored-by: Manuel Fuchs <[email protected]>
Signed-off-by: Terence Lee <[email protected]>
Co-authored-by: Manuel Fuchs <[email protected]>
Signed-off-by: Terence Lee <[email protected]>
Co-authored-by: Manuel Fuchs <[email protected]>
Signed-off-by: Terence Lee <[email protected]>
During the testing period, users and platforms can opt into the Rust launcher through three distinct entrypoints:

- Runtime Opt-In (App Developers) - The existing Go launcher will act as a shim. If a specific environment variable is present at runtime (e.g., `CNB_EXPERIMENTAL_RUST_LAUNCHER=true`), the Go launcher will immediately delegate execution to the Rust binary. This allows testing on any existing application image with both binaries.
- CLI Opt-In (Pack Users) - `pack` can introduce an experimental flag. When used, the exported OCI image will have its `ENTRYPOINT` permanently set to the Rust binary, bypassing the Go shim entirely.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hone / @jabrown85 / @Malax

When pack is running pack build we are suppose to include both binaries in the app image, then on runtime if app developer set CNB_EXPERIMENTAL_RUST_LAUNCHER=true will redirect to the other binary, but if pack build --<some-launcher-rust-flag> is used then pack should include the rust launcher in the app image only, is that how this CLI Opt-In would work?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it makes sense to just support the build path and not try to support the env var/runtime thing by shipping both launchers. While I think the env var makes it easier for app devs, it adds a lot of complexity that I'm not sure is worth it with the shim.

- versioning around the `launcher` can match the stability of the API surface area which is fairly stable

# Migration
[migration]: #migration

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migration Strategy: Cliff Release

We propose a cliff migration. The boundary is the lifecycle major version: 0.XX.X releases keep shipping the existing Go launcher, and 1.XX.X (along with every future major version) ships the new Rust launcher. There is no gradual swap or per-feature toggle. The version you pick determines which launcher you get.

Dual release window

For one quarter, the maintainers will dual release. The 0.XX.X line and the 1.XX.X line are published in parallel.

The purpose of this window is to absorb misses. If something in the Go launcher did not make its way into the Rust launcher correctly, the quarter gives us time to find it and fix it forward in the Rust implementation while the Go launcher is still available as a safety net.

What the window buys consumers

Builder and platform maintainers can stay on or revert to a 0.XX.X release if a critical bug in the Rust launcher affects their users. Reverting is a version pin, not a migration, so recovery is fast.

Consumers of the Go launcher library code get the same protection. During the quarter, the maintainers will make sure any launcher changes are also landed in the Go library on the 0.XX.X releases, so code depending on those packages continues to behave consistently while teams migrate.

After the quarter

Once the quarter ends, the 0.XX.X line is no longer maintained in parallel. At that point, previously public methods in the Go launcher library may be removed at the maintainers' discretion.

The intent is to keep as much as makes sense. Platform facing surfaces such as the launcher related files, structs, and validation are expected to stay stable so consumers of those pieces are not forced to change. The part that is expected to go away over time is the Go launcher implementation itself.


# Alternatives
[alternatives]: #alternatives

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not saying it's the perfect option, but have we considered VEX files as a solution? If the project shipped a VEX file, probably maintained via CI, that said the CVEs didn't impact lifecycle, users could pick that up and augment their scanner reports.

I'm not sure if that's sufficient for all use cases, but thought I'd throw it out there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants