Add multi-package Alpine packaging

This commit is contained in:
Joachim Schlöffel
2026-06-08 23:43:29 +02:00
parent d5a32abcd4
commit edc68c825b
22 changed files with 1013 additions and 146 deletions

View File

@@ -0,0 +1,28 @@
# Maintainer: Your Name <you@example.com>
pkgname=example-package
pkgver=0.1.0
pkgrel=0
pkgdesc="Short package description"
url="https://example.com/example-package"
arch="x86_64 aarch64"
license="Apache-2.0"
depends=""
makedepends="build-base"
subpackages="$pkgname-doc"
source="$pkgname-$pkgver.tar.gz::https://example.com/releases/$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"
build() {
make
}
check() {
make check
}
package() {
install -Dm755 "$builddir"/example-package "$pkgdir"/usr/bin/example-package
}
sha512sums="
"

View File

@@ -0,0 +1,26 @@
# Alpine Package Blueprint
Copy this directory to `packaging/alpine/local/<pkgname>/` and replace the
placeholder values before building.
Required:
- `APKBUILD`
Optional package-local hooks:
- `scripts/test-install.sh` validates README-style installation instructions.
- `scripts/update-generated-sources.sh` refreshes generated files that are
listed in `source=`.
Repo-level tasks discover packages from `packaging/alpine/local/*/APKBUILD`.
Limit a task to one or more packages with:
```sh
ALPINE_PACKAGE=<pkgname> mise run apk:build
ALPINE_PACKAGES="<pkg-a> <pkg-b>" mise run apk:build-all
ALPINE_PACKAGE=<pkgname> mise run apk:test-install
```
For compiled software, put normal Alpine build logic in `build()`, `check()`,
and `package()` and declare build tools in `makedepends`.

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-$(basename "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)")}"
alpine_version="${ALPINE_VERSION:-3.23}"
arch="${ALPINE_ARCH:-x86_64}"
case "${arch}" in
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
set -e
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
printf "%s\n" /repo >> /etc/apk/repositories
apk update
apk add "${PACKAGE_NAME}"
# Replace these with package-specific install assertions.
apk info -e "${PACKAGE_NAME}"
'

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
package_dir="${PACKAGE_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
printf 'No generated sources for %s\n' "${package_dir}"

View File

@@ -0,0 +1,57 @@
# Maintainer: Joachim Schlöffel <me@joachim-schloeffel.com>
pkgname=greptimedb
pkgver=1.0.2
pkgrel=0
pkgdesc="Cloud-native observability database for metrics, logs, and traces"
url="https://github.com/GreptimeTeam/greptimedb"
arch="x86_64"
license="Apache-2.0"
depends="ca-certificates"
makedepends="
binutils
cargo
clang
cmake
coreutils
lld
linux-headers
make
mold
openssl-dev
openssl-libs-static
perl
protobuf
protobuf-dev
rust
zlib-dev
zlib-static
zstd-dev
zstd-static
"
options="net"
source="$pkgname-$pkgver.tar.gz::https://github.com/GreptimeTeam/greptimedb/archive/refs/tags/v$pkgver.tar.gz"
export CARGO_HOME="$srcdir/cargo"
export CARGO_BUILD_JOBS="${CARGO_BUILD_JOBS:-2}"
export LIBRARY_PATH="/usr/lib"
build() {
cargo build \
--release \
--locked \
--bin greptime \
--features servers/dashboard
}
check() {
"$builddir"/target/release/greptime --version
}
package() {
install -Dm755 "$builddir"/target/release/greptime \
"$pkgdir"/usr/bin/greptime
}
sha512sums="
7f4ac722b84a26816030e65d504b37a53edfca15de669a4f6ee7a903f1a29c8358dcc2376a0a6cfd9ded13b0c5d7550a6856b9b10dc8cd080c6b12970553a0ea greptimedb-1.0.2.tar.gz
"

View File

@@ -0,0 +1,77 @@
# syntax=docker/dockerfile:1.7
ARG ALPINE_VERSION=3.23
ARG RUST_VERSION=1.90.0
FROM alpine:${ALPINE_VERSION} AS builder
ARG GREPTIMEDB_REF=main
ARG RUST_VERSION
RUN apk add --no-cache \
bash \
ca-certificates \
curl \
git \
build-base \
linux-headers \
clang \
lld \
mold \
cmake \
make \
perl \
pkgconf \
protobuf \
protobuf-dev \
zlib-dev \
zlib-static \
zstd-dev \
zstd-static \
openssl-dev \
openssl-libs-static \
binutils \
coreutils
ENV RUSTUP_HOME=/usr/local/rustup
ENV CARGO_HOME=/usr/local/cargo
ENV PATH=/usr/local/cargo/bin:${PATH}
ENV CARGO_BUILD_JOBS=2
ENV LIBRARY_PATH=/usr/lib
RUN curl https://sh.rustup.rs -sSf | sh -s -- \
-y \
--profile minimal \
--default-toolchain ${RUST_VERSION}
WORKDIR /src
RUN git clone https://github.com/GreptimeTeam/greptimedb.git . \
&& git checkout ${GREPTIMEDB_REF}
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git \
cargo build \
--release \
--locked \
--bin greptime \
--features servers/dashboard
RUN mkdir -p /out \
&& cp /src/target/release/greptime /out/greptime.debug \
&& cp /src/target/release/greptime /out/greptime \
&& strip /out/greptime \
&& ls -lh /out \
&& file /out/greptime \
&& ldd /out/greptime || true
FROM scratch AS artifact
COPY --from=builder /out/greptime /greptime
COPY --from=builder /out/greptime.debug /greptime.debug
FROM alpine:${ALPINE_VERSION} AS runtime
RUN apk add --no-cache ca-certificates
COPY --from=builder /out/greptime /usr/local/bin/greptime
ENTRYPOINT ["/usr/local/bin/greptime"]

View File

@@ -0,0 +1,53 @@
IMAGE ?= greptime-alpine-builder
RUNTIME_IMAGE ?= greptime-alpine
GREPTIMEDB_REF ?= main
ALPINE_VERSION ?= 3.23
RUST_VERSION ?= 1.90.0
OUT_DIR ?= dist
.PHONY: artifact image build inspect run clean
artifact:
mkdir -p $(OUT_DIR)
docker build \
--target artifact \
--build-arg GREPTIMEDB_REF=$(GREPTIMEDB_REF) \
--build-arg ALPINE_VERSION=$(ALPINE_VERSION) \
--build-arg RUST_VERSION=$(RUST_VERSION) \
--output type=local,dest=$(OUT_DIR) .
chmod +x $(OUT_DIR)/greptime
build:
docker build \
--target builder \
--build-arg GREPTIMEDB_REF=$(GREPTIMEDB_REF) \
--build-arg ALPINE_VERSION=$(ALPINE_VERSION) \
--build-arg RUST_VERSION=$(RUST_VERSION) \
-t $(IMAGE):$(GREPTIMEDB_REF) .
image:
docker build \
--target runtime \
--build-arg GREPTIMEDB_REF=$(GREPTIMEDB_REF) \
--build-arg ALPINE_VERSION=$(ALPINE_VERSION) \
--build-arg RUST_VERSION=$(RUST_VERSION) \
-t $(RUNTIME_IMAGE):$(GREPTIMEDB_REF) .
inspect: artifact
file $(OUT_DIR)/greptime
ldd $(OUT_DIR)/greptime || true
ls -lh $(OUT_DIR)/greptime $(OUT_DIR)/greptime.debug
run: image
docker run --rm -it \
-p 127.0.0.1:4000-4003:4000-4003 \
-v "$$(pwd)/greptimedb_data:/greptimedb_data" \
$(RUNTIME_IMAGE):$(GREPTIMEDB_REF) \
standalone start \
--http-addr 0.0.0.0:4000 \
--rpc-bind-addr 0.0.0.0:4001 \
--mysql-addr 0.0.0.0:4002 \
--postgres-addr 0.0.0.0:4003
clean:
rm -rf $(OUT_DIR)

View File

@@ -0,0 +1,33 @@
# GreptimeDB Alpine Package
This package builds `greptime` from the upstream GreptimeDB source release.
The old `Dockerfile` and `Makefile` in this directory are reference material for
the previous manual build. The APKBUILD uses the same build shape directly:
```sh
cargo build --release --locked --bin greptime --features servers/dashboard
```
## Package Commands
Refresh the source checksum after changing `pkgver`:
```sh
ALPINE_PACKAGE=greptimedb mise run apk:checksum
```
Build only this package:
```sh
ALPINE_PACKAGE=greptimedb mise run apk:build
```
Install-test an existing build without recompiling:
```sh
ALPINE_PACKAGE=greptimedb SKIP_BUILD=1 mise run apk:test-install
```
The full build can take close to an hour. Do not run it as part of lightweight
metadata or script checks.

View File

@@ -0,0 +1,47 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-greptimedb}"
alpine_version="${ALPINE_VERSION:-3.23}"
arch="${ALPINE_ARCH:-x86_64}"
case "${arch}" in
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-e "PACKAGE_NAME=${package_name}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
set -e
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
printf "%s\n" /repo >> /etc/apk/repositories
apk update
apk add "${PACKAGE_NAME}"
test -x /usr/bin/greptime
greptime --version
'

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
package_dir="${PACKAGE_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
printf 'No generated sources for %s\n' "${package_dir}"

View File

@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_name="${PACKAGE_NAME:-seaweedfs}"
alpine_version="${ALPINE_VERSION:-3.23}"
arch="${ALPINE_ARCH:-x86_64}"
case "${arch}" in
x86_64)
platform="${ALPINE_TEST_PLATFORM:-linux/amd64}"
;;
aarch64)
platform="${ALPINE_TEST_PLATFORM:-linux/arm64}"
;;
*)
printf 'unsupported Alpine architecture: %s\n' "${arch}" >&2
exit 2
;;
esac
if [[ "${SKIP_BUILD:-0}" != "1" ]]; then
ALPINE_PACKAGE="${package_name}" "${repo_root}/scripts/apk/build.sh" build "${arch}"
fi
if [[ ! -d "${repo_root}/packages/local/${arch}" ]]; then
printf 'missing local repository: packages/local/%s\n' "${arch}" >&2
printf 'run: ALPINE_PACKAGE=%s mise run apk:build\n' "${package_name}" >&2
exit 1
fi
docker run --rm --platform "${platform}" \
-e "ALPINE_ARCH=${arch}" \
-v "${repo_root}/packages/local:/repo:ro" \
"alpine:${alpine_version}" \
sh -lc '
set -e
cp "/repo/${ALPINE_ARCH}"/*.rsa.pub /etc/apk/keys/
printf "%s\n" /repo >> /etc/apk/repositories
apk update
apk add seaweedfs \
seaweedfs-master-openrc \
seaweedfs-volume-openrc \
seaweedfs-filer-openrc
test -x /usr/bin/weed
test -d /etc/seaweedfs
test -f /etc/seaweedfs/master.toml
test -f /etc/seaweedfs/filer.toml
test -f /etc/conf.d/seaweedfs.master
test -f /etc/conf.d/seaweedfs.volume
test -f /etc/conf.d/seaweedfs.filer
test -f /etc/init.d/seaweedfs.master
test -f /etc/init.d/seaweedfs.volume
test -f /etc/init.d/seaweedfs.filer
weed version
rc-update add seaweedfs.master default
rc-update add seaweedfs.volume default
rc-update add seaweedfs.filer default
test -L /etc/runlevels/default/seaweedfs.master
test -L /etc/runlevels/default/seaweedfs.volume
test -L /etc/runlevels/default/seaweedfs.filer
apk add seaweedfs-doc bash-completion
apk info -e seaweedfs-bash-completion
test -d /usr/share/doc/seaweedfs/examples
test -f /usr/share/doc/seaweedfs/examples/master.toml
test -f /usr/share/bash-completion/completions/weed
'

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="${REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../../.." && pwd)}"
package_dir="${PACKAGE_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
configs=(credential filer master notification replication security shell)
for config in "${configs[@]}"; do
"${repo_root}/bin/weed" scaffold -config "${config}" 2>/dev/null \
> "${package_dir}/example-${config}.toml"
done
"${repo_root}/bin/weed" autocomplete bash 2>/dev/null \
| sed -E 's#complete -C "?[^"]*/weed"? weed#complete -C /usr/bin/weed weed#' \
> "${package_dir}/weed.bash-completion"