{"id":49801216,"url":"https://github.com/erlef/erlang-build-proposal","last_synced_at":"2026-05-12T14:09:24.543Z","repository":{"id":332947227,"uuid":"1116895931","full_name":"erlef/erlang-build-proposal","owner":"erlef","description":"Proposal for unified Erlang/OTP binary distribution infrastructure","archived":false,"fork":false,"pushed_at":"2026-02-26T23:49:58.000Z","size":37,"stargazers_count":3,"open_issues_count":3,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-02-27T05:48:40.978Z","etag":null,"topics":["binary","distribution","erlang"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erlef.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":["https://members.erlef.org/join-us","https://erlef.org/sponsors#become-a-sponsor"]}},"created_at":"2025-12-15T14:34:29.000Z","updated_at":"2026-02-26T23:50:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/erlef/erlang-build-proposal","commit_stats":null,"previous_names":["erlef/erlang-build","erlef/erlang-build-proposal"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/erlef/erlang-build-proposal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlef%2Ferlang-build-proposal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlef%2Ferlang-build-proposal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlef%2Ferlang-build-proposal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlef%2Ferlang-build-proposal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erlef","download_url":"https://codeload.github.com/erlef/erlang-build-proposal/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlef%2Ferlang-build-proposal/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32942342,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-12T09:19:52.626Z","status":"ssl_error","status_checked_at":"2026-05-12T09:17:33.438Z","response_time":102,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary","distribution","erlang"],"created_at":"2026-05-12T14:09:23.108Z","updated_at":"2026-05-12T14:09:24.532Z","avatar_url":"https://github.com/erlef.png","language":null,"funding_links":["https://members.erlef.org/join-us","https://erlef.org/sponsors#become-a-sponsor"],"categories":[],"sub_categories":[],"readme":"# Erlang Builds\n\n\u003e **Status: Proposal/RFC** - This document outlines a proposal by the\n[Erlang Ecosystem Foundation (EEF)](https://erlef.org/) to create a unified\nErlang/OTP binary distribution infrastructure.\n\n## Motivation\n\nThe Erlang/OTP binary distribution landscape is fragmented. As the [Current\nProviders](#current-providers) table below shows, numerous projects each solve\npart of the problem. Some focus on specific platforms, others on particular use\ncases, but no single provider offers comprehensive coverage across all operating\nsystems, architectures, and build configurations.\n\nThis fragmentation creates several challenges:\n\n**Difficulty running the latest Erlang release.** Building Erlang/OTP from\nsource requires installing toolchains, satisfying dependencies, and navigating\nplatform-specific quirks, many of which are poorly documented. Package managers\nlike apt, brew, and chocolatey often lag behind official releases by weeks or\nmonths. Users who need a specific version for a specific platform may find no\npre-built binary exists.\n\n**Duplicated effort across downstream projects.** Products built on Erlang,\nsuch as RabbitMQ, Livebook, and tools using Burrito for packaging, must each\nsolve binary distribution independently. This leads to repeated work and\ninconsistent approaches across the ecosystem.\n\n**Regulatory compliance burden.** The EU Cyber Resilience Act (CRA) introduces\nrequirements for software supply chain transparency, including SBOMs, VEX\ndisclosures, and timely security patches. Meeting these requirements is simpler\nwhen builds come from a single, well-maintained source rather than a patchwork\nof providers with varying practices.\n\n**Lack of a consolidation point.** Without an official, EEF-endorsed\ndistribution, the ecosystem has no standard to rally around. A central\ninitiative with a defined maintenance process, not reliant on individual\nmaintainer availability, gives providers and users a sustainable foundation to\nbuild upon, reducing fragmentation over time.\n\n## Goals\n\n* Provide Central \u0026 Official Erlang Binary Distribution for the Ecosystem\n  - Endorsed by Erlang, downloadable on erlang.org\n* Reduce Fragmentation of the Space through many providers doing a part of the problem\n* Provide Build SBoM with builds\n* Provide SLSA Provenance with Builds\n* Wide Range of supported Arch / OS\n\n## Current Providers\n\nThe following tables list some Erlang/OTP providers based on provider types. They are listed here in order\nto get a good overview about how Erlang/OTP are being packaged by different OSS vendors.\n\n### Erlang Binary providers\n\n| Provider | Linux x64 | Linux ARM64 | macOS x64 | macOS ARM64 | Windows x64 | Binary | Docker | Notes |\n|----------|-----------|-------------|-----------|-------------|-------------|--------|--------|-------|\n| [Erlang OTP](https://github.com/erlang/otp) | | | | | ✓ | ✓ | | Official builds |\n| [Erlef OTP Builds](https://github.com/erlef/otp_builds) | | | ✓ | ✓ | | ✓ | | |\n| [BEAM Machine](https://github.com/doawoo/beam-machine) | ✓ | ✓ | ✓ | ✓ | | ✓ | | MUSL Linux, Fat macOS builds |\n| [Erlang Solutions](https://www.erlang-solutions.com/downloads-2/) | ✓ | | ✓ | | ✓ | ✓ | | Ubuntu, Debian, Fedora, CentOS, Raspbian |\n| [Hex.pm Bob](https://github.com/hexpm/bob) | ✓ | ✓ | ✓ | ✓ | | ✓ | ✓ | Ubuntu 20.04/22.04/24.04 |\n| [Burrito Erlang Builder](https://github.com/burrito-elixir/erlang-builder) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | | OTP 25.3+, for Burrito |\n| [BEAM runtime](https://meta-erlang.github.io/beamruntime/intro/) | ✓ | ✓ | | | | ✓ | ✓ | runtime relocated based on libc or musl |\n| [Alpine Linux](https://pkgs.alpinelinux.org/package/v3.21/community/x86/erlang) | ✓ | ✓ | | | | ✓ | | musl-based, also armhf/armv7/ppc64le/s390x |\n| [Docker Erlang OTP](https://github.com/erlang/docker-erlang-otp) | ✓ | ✓ | | | | | ✓ | Official Docker library image |\n| [Elixir Desktop Runtimes](https://github.com/elixir-desktop/runtimes) | | | | | | ✓ | | Android \u0026 iOS runtimes |\n| [Gleam Erlang Linux Builds](https://github.com/gleam-community/erlang-linux-builds) | ✓ | ✓ | | | | ✓ | | glibc, musl, static variants |\n| [erlang-dist](https://github.com/benoitc/erlang-dist) | ✓ | ✓ | | ✓ | | ✓ | | Ubuntu, Debian, Rocky Linux, CentOS Stream, macOS |\n\n### Erlang Source build tools\n\n| Provider | Notes |\n|----------|-------|\n| [kerl](https://github.com/kerl/kerl) | Easy building and installing of Erlang/OTP instances |\n| [asdf erlang plugin](https://github.com/asdf-vm/asdf-erlang) | Erlang plugin for asdf version manager | \n| [mise erlang plugin](https://mise.jdx.dev/lang/erlang.html) | Erlang plugin for mise version manager | \n\n### Package management\n\n| Provider | Notes |\n|----------|-------|\n| [nix](https://github.com/NixOS/nixpkgs/tree/nixos-25.11/pkgs/development/interpreters/erlang) | nix package | \n| [erlang chocolatey](https://community.chocolatey.org/packages/erlang) | Erlang package for Windows using https://chocolatey.org/ |\n| [brew](https://formulae.brew.sh/formula/erlang) | package for Linux and MacOs|\n\n### Erlang source build for embedded and custom Linux distributions\n\n| Provider | Notes |\n|----------|-------|\n| [erlang package](https://github.com/buildroot/buildroot/tree/master/package/erlang) | Erlang for buildroot |\n| [erlang recipe](https://github.com/meta-erlang/meta-erlang/tree/master/recipes-devtools/erlang) | Erlang recipe for Yocto Project |\n\n### Erlang source/binary package for Operation Systems\n\n| Provider/Operation System| Notes |\n|----------|-------|\n| [debian](https://tracker.debian.org/pkg/erlang) | |\n| [suse](https://packagehub.suse.com/packages/erlang) | |\n| [fedora](https://packages.fedoraproject.org/pkgs/erlang/erlang/) | | \n| [freebsd](https://cgit.freebsd.org/ports/tree/lang/erlang) | Also per version [erlang-runtime28](https://cgit.freebsd.org/ports/tree/lang/erlang-runtime28)\n| [openbsd](https://github.com/openbsd/ports/tree/master/lang/erlang) | Also per version, 26, 27 and 28 |\n| [netbsd](https://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/lang/erlang/index.html) | single version [support for 27](https://github.com/NetBSD/pkgsrc/tree/trunk/lang/erlang/)|\n\n## Possible Future Consumers\n\nThe following tools and projects could potentially integrate with the official Erlang builds. They could use the Discovery API to locate appropriate releases, download binaries directly from the OCI registry, and verify artifact integrity using cosign signatures.\n\n### Version Managers \u0026 CI Tools\n* [asdf erlang plugin](https://github.com/asdf-vm/asdf-erlang)\n* [winget](https://github.com/microsoft/winget-cli)\n* [Homebrew](https://github.com/Homebrew/homebrew-core/blob/master/Formula/e/erlang.rb)\n* [Elixir install.sh](https://elixir-lang.org/install.sh)\n* [Hex.pm Bob](https://github.com/hexpm/bob) consumers\n* [erlef/setup-beam GitHub Action](https://github.com/erlef/setup-beam)\n\n### Cross-Architecture Release Builders\n\nDevelopers building products that ship Erlang releases for multiple target architectures. Using rebar3's `include_erts` option, they can bundle a pre-built Erlang runtime for a different architecture than their build machine (e.g., building on x86-64 but targeting aarch64).\n\nExamples include:\n* [RabbitMQ](https://github.com/rabbitmq/rabbitmq-server) - ships releases for multiple platforms\n* [OpenRiak](https://github.com/OpenRiak/riak) - distributed database with multi-platform releases\n* Any project using rebar3 releases with cross-architecture deployment targets\n\n## Requirements\n\nNot all of those requirements need to be fulfilled to get started.\n\n### Platform Support\n* Needs to be able to build at least (not limited to the following list):\n  * Linux\n    * x86-64\n    * aarch64\n    * armv7, aarch32\n  * macOS\n    * aarch64\n  * Windows\n    * x86-64\n* Each supported OS needs to support SBoM. Build Attestations are acceptable\n* Needs to be able to build common architectures on the OS\n* Ability to easily add new architecture for each OS\n\n### Build Artifacts\n* Creates Build SBoMs for Builds\n  - [CycloneDX](https://cyclonedx.org/) \u0026 [SPDX](https://spdx.dev/) Formats\n* Creates verifiable [SLSA](https://slsa.dev/) Provenance for Builds\n* Windows builds signed via Azure Trusted Signing\n* macOS builds notarized (infrastructure TBD)\n* Can build multiple flavors, Examples:\n  - Dynamically Linked vs Statically Linked\n  - Different Library Support like OpenSSL v1 vs v3\n  - FIPS Enabled\n  - MUSL / Libc portable (for burrito)\n\n### Lifecycle Management\n* Builds are created for each non EOL Erlang Version\n* New Build Flavors can be added retroactively for all non EOL versions\n* Append Only (old artifacts stay, but tags can be pointed to a newer revision)\n* Can rebuild for library updates / security patches\n\n### Infrastructure\n* Tracks all Build in a SBoM Management Tool like [Dependency Track](https://dependencytrack.org/)\n* Reproducible Builds - Provide a reproducible build platform for the builds (lib versions etc.)\n* Offers a Discovery API to locate the right image for the user (OS / Arch, OTP Version, Flavor, Library versions etc.)\n* Can profit from free OSS Infrastructure like CI, Storage \u0026 CDN\n\n### Release Testing\n* Builds undergo release testing to validate outputs before publication\n* Full OTP test suite is comprehensive and resource-intensive; only a selected subset runs\n* Selected tests verify:\n  - Binary functionality (can start BEAM, run basic commands)\n  - Platform-specific linking (OpenSSL, ncurses, etc.)\n  - Cross-platform consistency\n* Tests prove the build works; they don't replace OTP's upstream testing\n\n## Design Proposal\n\n```mermaid\nflowchart TB\n    subgraph GitHub[\"GitHub\"]\n        Repo[\"Repository\u003cbr/\u003e(Config, Workflows)\"]\n        Actions[\"GitHub Actions\"]\n        GHCR[\"GitHub Container Registry\u003cbr/\u003e(GHCR)\"]\n    end\n\n    subgraph Orchestrator[\"Orchestrator Application\"]\n        BuildOrch[\"Build Orchestrator\"]\n        API[\"Public API\"]\n    end\n\n    subgraph BuildInfra[\"Build Infrastructure\"]\n        Linux[\"Linux Build SDK\u003cbr/\u003e(Yocto + QEMU)\"]\n        macOS[\"macOS Build SDK\u003cbr/\u003e(Nix)\"]\n        Windows[\"Windows Build SDK\u003cbr/\u003e(WSL + MSVC)\"]\n        Tests[\"Release Tests\u003cbr/\u003e(Smoke Tests)\"]\n    end\n\n    subgraph Artifacts[\"Build Artifacts\"]\n        Binaries[\"Erlang/OTP Binaries\"]\n        Docker[\"Docker Images\"]\n        SBOM[\"SBOMs\u003cbr/\u003e(CycloneDX/SPDX)\"]\n        SLSA[\"SLSA Provenance\"]\n    end\n\n    DT[\"Dependency Track\u003cbr/\u003e(SBOM Management)\"]\n    Users[\"Users / Downstream Tools\"]\n\n    Repo --\u003e Actions\n    Actions --\u003e Linux \u0026 macOS \u0026 Windows\n    Linux \u0026 macOS \u0026 Windows --\u003e Tests\n    Tests --\u003e Binaries \u0026 Docker\n    Binaries --\u003e GHCR\n    Docker --\u003e GHCR\n    SBOM --\u003e GHCR\n    SLSA --\u003e GHCR\n    SBOM --\u003e DT\n    BuildOrch --\u003e Actions\n    BuildOrch \u003c--\u003e GHCR\n    API \u003c--\u003e GHCR\n    API --\u003e Users\n    Users --\u003e GHCR\n```\n\n* Using ORAS (OCI Registry As Storage) for Binary Storage / Exchange - https://oras.land/\n* Using OCI for Docker Builds\n* Using GitHub for\n  - Repository containing API, Config, CI Workflows\n  - GitHub OCI Registry\n* Pluggable Build Infrastructure\n  - Using GitHub Actions for initial OS support\n  - Other Build Runners can be added using separate Infrastructure, for example if we ever wanted to provide BSD Builds\n* Reproducible Build Infra\n  - [Linux Build SDK](linux-build-sdk.md) using [Yocto Project](https://www.yoctoproject.org/) and QEMU\n  - [Mac Build SDK](mac-build-sdk.md) using [Nix](https://nixos.org/)\n  - [Windows Build SDK](windows-build-sdk.md): TBD\n* Dependency Track to store all Build SBoM / Track Vulnerabilities\n* Support for building intermediate artifacts. For example not all OTP Apps need a recompile for a different infrastructure\n* Observer CLI for Build SBoM? - https://docs.sbom.observer/getting-started/observer-cli\n* OCI Registry is primary keeper of State, not a database\n\n### API\n\n```mermaid\nflowchart LR\n    subgraph Orchestrator[\"Orchestrator Application\"]\n        subgraph BuildOrch[\"Build Orchestrator\"]\n            ConfigCheck[\"Check Build Config\u003cbr/\u003evs Built Artifacts\"]\n            LibCheck[\"Check Library Versions\u003cbr/\u003e(Security Updates)\"]\n            Scheduler[\"Job Scheduler\"]\n        end\n\n        subgraph PublicAPI[\"Public API\"]\n            Status[\"Build Status\u003cbr/\u003e(Done/Planned/Errors)\"]\n            Discovery[\"Discovery API\"]\n            Metadata[\"Build Metadata\u003cbr/\u003e(Vulnerabilities)\"]\n        end\n    end\n\n    Config[\"Build Configuration\"] --\u003e ConfigCheck\n    OTPVersions[\"OTP Versions\"] --\u003e ConfigCheck\n    ConfigCheck --\u003e Scheduler\n    LibCheck --\u003e Scheduler\n    Scheduler --\u003e |\"Trigger Builds\"| GHA[\"GitHub Actions\"]\n\n    GHCR[\"GitHub Container\u003cbr/\u003eRegistry\"]\n    GHA --\u003e GHCR\n    GHCR \u003c--\u003e Status\n    GHCR \u003c--\u003e Discovery\n    GHCR \u003c--\u003e Metadata\n\n    Users[\"Users / Tools\"]\n    Users --\u003e |\"Query builds\"| Discovery\n    Discovery --\u003e |\"Redirect to artifact\"| GHCR\n    Users --\u003e |\"Direct pull\"| GHCR\n```\n\nThe project will run an orchestrator application. Its job is twofold:\n* Build Orchestrator\n  - Check Build Configuration \u0026 OTP Versions against built artifacts\n    * Schedules jobs to create missing builds\n  - Check Library Versions (manual change / security updates) and re-schedules\n    builds where necessary\n* Public API\n  - Build Status (Done / Planned / Errors)\n  - Discovery\n    * Filter builds by criteria to locate the correct build for a user\n    * Provide Redirect to OCI Artifact without needing to understand ORAS on the client\n    * Provide metadata for build like vulnerable status\n\n### ORAS Structure\n\n```mermaid\nflowchart TB\n    subgraph Registry[\"ghcr.io/erlef/erlang-builds\"]\n        subgraph BinaryRepo[\"erlang-musl:27.0\"]\n            ImageIndex1[\"Image Index\u003cbr/\u003e(multi-arch manifest)\"]\n            subgraph Platforms1[\"Platform Manifests\"]\n                AMD64_1[\"linux/amd64\"]\n                ARM64_1[\"linux/arm64\"]\n            end\n            subgraph Layers1[\"Layers (per OTP app)\"]\n                ERTS[\"erts\"]\n                Kernel[\"kernel\"]\n                StdLib[\"stdlib\"]\n                SSL[\"ssl\"]\n                More[\"...\"]\n            end\n            ImageIndex1 --\u003e AMD64_1 \u0026 ARM64_1\n            AMD64_1 \u0026 ARM64_1 --\u003e Layers1\n        end\n\n        subgraph DockerRepo[\"erlang-musl-alpine:27.0\"]\n            ImageIndex2[\"Image Index\u003cbr/\u003e(multi-arch manifest)\"]\n            subgraph Platforms2[\"Platform Manifests\"]\n                AMD64_2[\"linux/amd64\"]\n                ARM64_2[\"linux/arm64\"]\n            end\n            subgraph DockerImg[\"Docker Image\"]\n                AllApps[\"All OTP apps included\"]\n            end\n            ImageIndex2 --\u003e AMD64_2 \u0026 ARM64_2\n            AMD64_2 \u0026 ARM64_2 --\u003e DockerImg\n        end\n\n        subgraph Attached[\"Attached Artifacts\u003cbr/\u003e(via referrers API)\"]\n            SBOM_Art[\"SBOM\u003cbr/\u003e(CycloneDX)\"]\n            SLSA_Art[\"SLSA Provenance\"]\n        end\n\n        BinaryRepo -.-\u003e Attached\n        DockerRepo -.-\u003e Attached\n    end\n\n    Client[\"Client\"] --\u003e |\"1 Pull tag 27.0\"| ImageIndex1\n    Client --\u003e |\"2 Select platform\"| AMD64_1\n    Client --\u003e |\"3 GET /referrers/digest\"| Attached\n```\n\nArtifacts are stored in GitHub Container Registry using the\n[OCI Distribution Spec](https://github.com/opencontainers/distribution-spec)\n(compatible with any OCI registry).\n\n#### Repository Naming\n* Binary builds: `ghcr.io/erlef/erlang-builds/erlang-[FLAVOR]` (e.g., `erlang-musl`, `erlang-openssl3`)\n* Docker images: `ghcr.io/erlef/erlang-builds/erlang-[FLAVOR]-[BASE]` (e.g., `erlang-musl-alpine`)\n\n#### Structure per Repository\n```\nghcr.io/erlef/erlang-builds/erlang-musl:27.0\n├── Image Index (multi-arch manifest)\n│   ├── linux/amd64 → Image Manifest\n│   │   └── Layers (one per OTP app: erts, kernel, stdlib, ssl, ...)\n│   └── linux/arm64 → Image Manifest\n│       └── Layers (one per OTP app)\n└── Attached Artifacts (via OCI referrers API)\n    ├── SBOM (CycloneDX)\n    └── SLSA Provenance\n\nghcr.io/erlef/erlang-builds/erlang-musl-alpine:27.0\n├── Image Index (multi-arch manifest)\n│   ├── linux/amd64 → Docker Image (all apps included)\n│   └── linux/arm64 → Docker Image (all apps included)\n└── Attached Artifacts\n    ├── SBOM (CycloneDX)\n    └── SLSA Provenance\n```\n\n#### Key Concepts\n* **Tag** = OTP version (e.g., `27.0`, `26.2.5`)\n* **Image Index** = multi-arch entry point, clients select platform via `Accept` header or registry API\n* **Layers** = one layer per OTP application, enabling partial installation for binary builds\n* **Attached Artifacts** = SBOMs and attestations linked via `subject` field, discoverable via `/v2/.../referrers/\u003cdigest\u003e` API\n* **Annotations** = build metadata (workflow, library versions, build timestamp)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferlef%2Ferlang-build-proposal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferlef%2Ferlang-build-proposal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferlef%2Ferlang-build-proposal/lists"}