Releases
Each release on the Releases page
carries modbee ready to run - no compiler, nothing to install beside it -
and the Docker image is published under the same version.
| File | For |
|---|---|
modbee-<version>-linux-x86_64.tar.gz |
Linux on x86-64: one static binary, any distribution |
modbee-<version>-linux-arm64.tar.gz |
Linux on ARM 64-bit: a Raspberry Pi 4 or 5, an ARM server |
modbee-<version>-windows-x86_64.zip |
Windows on x86-64: modbee.exe, one file (windows.md) |
*.cdx.json |
Each one's SBOM (CycloneDX): every library inside it, with its version and licence |
*.sigstore.json |
Each file's signature |
SHA256SUMS |
The checksum of every file |
| Docker | ghcr.io/mod-bee/modbee-mqtt:<version>, amd64 and arm64 (docker.md) |
Every binary is the whole of it: the broker (modbee serve), the Kafka pipe,
the Application API and every command. It says so itself:
$ modbee --version
modbee 0.1.0 (TLS: OpenSSL)
Kafka pipe: librdkafka 2.15.1 (gzip snappy ssl sasl regex lz4 sasl_gssapi sasl_plain sasl_scram plugins zstd sasl_oauthbearer)
Application API: gRPC 1.81.1
The Linux binary is linked statically against musl, so it runs on any Linux
of its architecture - Debian, Ubuntu, RHEL, Alpine, a distribution from ten
years ago - with nothing else installed.
Installing on Linux
tar xzf modbee-0.1.0-linux-x86_64.tar.gz
sudo install modbee-0.1.0-linux-x86_64/modbee /usr/local/bin/
modbee --version
Run as a service with systemd - Restart=always is also what brings it back
after a setting that needs a restart (settings.md):
# /etc/systemd/system/modbee.service
[Unit]
Description=ModBee MQTT
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/modbee serve --config /etc/modbee/modbee.yaml
Restart=always
User=modbee
StateDirectory=modbee
[Install]
WantedBy=multi-user.target
sudo useradd --system --no-create-home modbee
sudo systemctl enable --now modbee
Installing on Windows
Unzip it anywhere; modbee.exe service install makes it a Windows service
(windows.md).
Checking a download
Three ways, each enough on its own. They prove the file was built by this
repository's release workflow from the tagged commit, and not changed since.
GitHub's attestation - with the GitHub CLI:
gh attestation verify modbee-0.1.0-linux-x86_64.tar.gz --repo mod-bee/modbee-mqtt
Sigstore - with cosign,
and the file's .sigstore.json beside it:
cosign verify-blob modbee-0.1.0-linux-x86_64.tar.gz \
--bundle modbee-0.1.0-linux-x86_64.tar.gz.sigstore.json \
--certificate-identity https://github.com/mod-bee/modbee-mqtt/.github/workflows/release.yml@refs/tags/v0.1.0 \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
The checksum - against SHA256SUMS, which is itself signed and attested
the same way:
sha256sum --check --ignore-missing SHA256SUMS
On Windows: Get-FileHash modbee-0.1.0-windows-x86_64.zip and compare with
its line in SHA256SUMS.
Making a release
-
The version, the same in both places:
project(... VERSION x.y.z)in
CMakeLists.txt, andversion=inlibrary.properties(the Arduino
Library Manager reads it). -
The notes: in CHANGELOG.md, what is under
Unreleased moves to a new## [x.y.z]section. That section is the
release's notes. -
Try it (optional, recommended): Actions → release → Run workflow on
main. It builds, tests, signs and checks everything a tag would, and
leaves the files on the run instead of publishing them. The first run
fills the build caches - gRPC from source, most of an hour - so the tagged
run after it takes minutes. -
Tag and push:
git tag v0.1.0 git push origin v0.1.0
The release workflow (.github/workflows/release.yml) refuses a tag that is
not the version in both files, or a version with no CHANGELOG section,
before it builds anything. A build without the Kafka pipe or the
Application API - or a Linux binary that is not static, or a Windows one
that needs a DLL Windows does not have - stops it too. Nothing is published
until all three binaries are built, tested and signed. docker.yml publishes
the image from the same tag.
To build the Linux binary on your own machine, with only Docker:
docker run --rm -v "$PWD":/src -w /src alpine:3.22 sh scripts/release/build-linux.sh
It leaves the same .tar.gz and SBOM in dist/ (build-linux.sh).