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

432
README.md
View File

@@ -1,26 +1,222 @@
# SeaweedFS Alpine Package
# Alpine Packages
Local Alpine 3.23 packaging for SeaweedFS `4.31`. The workflow runs Alpine tooling
inside Docker and writes signed packages under `packages/local/<arch>/`.
Alpine 3.23 packaging for internal packages.
## Commands
This repository builds signed `x86_64` and `aarch64` APKs and publishes them to
the Gitea Alpine package registry under:
```text
https://code.factoring.digital/api/packages/fsp-ops/alpine/v3.23/seaweedfs-alpine
```
## Use In Production
### Add The Package Repository
Install the registry signing key on each Alpine node:
```sh
curl -fsSLo /etc/apk/keys/fsp-ops-alpine.rsa.pub \
https://code.factoring.digital/api/packages/fsp-ops/alpine/key
```
Add the package repository:
```sh
printf '%s\n' \
'https://code.factoring.digital/api/packages/fsp-ops/alpine/v3.23/seaweedfs-alpine' \
>> /etc/apk/repositories
apk update
```
If the registry is private, include a Gitea user and package token in the
repository URL:
```text
https://<user>:<token>@code.factoring.digital/api/packages/fsp-ops/alpine/v3.23/seaweedfs-alpine
```
### Install SeaweedFS Node Roles
Install the base package plus only the OpenRC role packages needed on that node.
For a single-node test or a compact small deployment:
```sh
apk add seaweedfs \
seaweedfs-master-openrc \
seaweedfs-volume-openrc \
seaweedfs-filer-openrc
```
For separated production nodes, install only the role running there:
```sh
apk add seaweedfs seaweedfs-master-openrc
apk add seaweedfs seaweedfs-volume-openrc
apk add seaweedfs seaweedfs-filer-openrc
```
Available OpenRC role packages:
```text
seaweedfs-master-openrc -> /etc/init.d/seaweedfs.master
seaweedfs-volume-openrc -> /etc/init.d/seaweedfs.volume
seaweedfs-filer-openrc -> /etc/init.d/seaweedfs.filer
seaweedfs-s3-openrc -> /etc/init.d/seaweedfs.s3
seaweedfs-webdav-openrc -> /etc/init.d/seaweedfs.webdav
seaweedfs-sftp-openrc -> /etc/init.d/seaweedfs.sftp
seaweedfs-admin-openrc -> /etc/init.d/seaweedfs.admin
seaweedfs-worker-openrc -> /etc/init.d/seaweedfs.worker
```
The package name is `seaweedfs`, matching Alpine aports. If a node already has
Alpine's old generic OpenRC package installed, remove it before installing a
role-specific split:
```sh
apk del seaweedfs-openrc
apk add seaweedfs seaweedfs-master-openrc
```
### Configure Services
Runtime files are installed in the usual Alpine locations:
```text
/usr/bin/weed
/etc/seaweedfs/*.toml
/etc/conf.d/seaweedfs.*
/etc/init.d/seaweedfs.*
```
Edit `/etc/conf.d/seaweedfs.<role>` for command-line flags and
`/etc/seaweedfs/*.toml` for SeaweedFS config. The packaged defaults are short
and production-neutral; full upstream example configs are in:
```text
/usr/share/doc/seaweedfs/examples/
```
Enable and start only the services needed on the node:
```sh
rc-update add seaweedfs.master default
rc-service seaweedfs.master start
rc-update add seaweedfs.volume default
rc-service seaweedfs.volume start
rc-update add seaweedfs.filer default
rc-service seaweedfs.filer start
```
Check the installed binary and service state:
```sh
weed version
rc-service seaweedfs.master status
```
### Optional Packages
Install docs and generated examples:
```sh
apk add seaweedfs-doc
```
Install bash completion:
```sh
apk add bash-completion seaweedfs-bash-completion
```
`seaweedfs-bash-completion` is also selected automatically when `seaweedfs` and
`bash-completion` are installed together.
### Upgrade Or Pin
Use normal Alpine package operations:
```sh
apk upgrade seaweedfs
rc-service seaweedfs.master restart
```
Pin a specific package build when needed:
```sh
apk add seaweedfs=4.31-r3
```
### Install GreptimeDB
Install GreptimeDB:
```sh
apk add greptimedb
```
Check the installed binary:
```sh
greptime --version
```
## Background And Contribution
### Package Layout
Package sources live under:
```text
packaging/alpine/local/<pkgname>/
```
Currently packaged:
```text
seaweedfs SeaweedFS 4.31 release binary and OpenRC role splits
greptimedb GreptimeDB 1.0.2 built from source for x86_64
```
### SeaweedFS Package
The APKBUILD repackages the official SeaweedFS Linux release tarballs. It does
not build SeaweedFS from source. The package installs:
- `weed` as `/usr/bin/weed`
- minimal active config under `/etc/seaweedfs/`
- role-specific OpenRC subpackages
- upstream example configs under `/usr/share/doc/seaweedfs/examples/`
- generated bash completion as a separate subpackage
Local build output is written under:
```text
packages/local/<arch>/
```
Signing keys and distfiles are cached under:
```text
.cache/abuild/
.cache/apk-distfiles/
```
### Build Commands
```sh
mise run apk:lint
mise run apk:build
mise run apk:build-all
mise run apk:build-x86_64
mise run apk:build-aarch64
mise run apk:update-generated
mise run apk:checksum
mise run apk:lint
mise run apk:packages
mise run apk:smoke
mise run apk:test-install
mise run apk:test-shell
mise run apk:publish-check
mise run apk:publish-gitea
mise run gitea-workflow-build
mise run apk:shell
mise run apk:clean
```
`apk:build` targets `x86_64` by default. Multi-arch builds target `x86_64` and
@@ -30,116 +226,121 @@ mise run apk:clean
ALPINE_ARCHES="x86_64 aarch64" mise run apk:build-all
```
The release binary is also exposed as a mise HTTP tool stub:
Unqualified build and install-test tasks discover all packages. GreptimeDB is a
source build and can take close to an hour; it is limited to `x86_64` during
production evaluation. Target fast package work explicitly:
Build or test a subset of packages with `ALPINE_PACKAGE` or `ALPINE_PACKAGES`:
```sh
./bin/weed version
ALPINE_PACKAGE=seaweedfs mise run apk:build
ALPINE_PACKAGES="seaweedfs other-package" mise run apk:build-all
ALPINE_PACKAGE=seaweedfs mise run apk:test-install
ALPINE_PACKAGE=greptimedb mise run apk:checksum
ALPINE_PACKAGE=greptimedb mise run apk:build
ALPINE_PACKAGE=greptimedb SKIP_BUILD=1 mise run apk:test-install
```
## Package Layout
Use the test shell to inspect the package in Alpine with the current build
installed:
```sh
ALPINE_PACKAGE=seaweedfs mise run apk:shell
mise run apk:test-shell
```
Use the install test to validate the production instructions against the local
package repository in a fresh Alpine container:
```sh
mise run apk:test-install
```
Use `SKIP_BUILD=1` to reuse existing local packages:
```sh
SKIP_BUILD=1 mise run apk:test-install
SKIP_BUILD=1 mise run apk:test-shell
```
### Adding Packages
Each package lives under:
```text
packaging/alpine/local/<pkgname>/
```
The only required file is `APKBUILD`. Package-specific helpers can be added as
hooks:
```text
packaging/alpine/local/<pkgname>/scripts/test-install.sh
packaging/alpine/local/<pkgname>/scripts/update-generated-sources.sh
```
Repo-level tasks discover all `packaging/alpine/local/*/APKBUILD` files. Hook
tasks skip packages that do not provide the requested hook.
Start new packages from the blueprint:
```text
packaging/alpine/blueprint/
```
For compiled software, declare build tools in `makedepends` and use normal
Alpine `build()`, `check()`, and `package()` functions in the package's
`APKBUILD`.
### Generated Package Sources
Generated files should live next to the package's `APKBUILD` so
`abuild checksum` can track them as ordinary package sources. For SeaweedFS,
that includes:
```text
packaging/alpine/local/seaweedfs/APKBUILD
packaging/alpine/local/seaweedfs/*.toml
packaging/alpine/local/seaweedfs/example-*.toml
packaging/alpine/local/seaweedfs/weed.bash-completion
packaging/alpine/local/seaweedfs/seaweedfs.*.confd
packaging/alpine/local/seaweedfs/seaweedfs.initd
packages/local/<arch>/
```
The package repackages upstream release tarballs, so builds use
`ALPINE_BUILD_PLATFORM=linux/amd64` by default. Signing keys and distfiles are
cached in `.cache/abuild/` and `.cache/apk-distfiles/`.
The Gitea workflow publishes to the Alpine package registry branch `v3.23`.
Override `ALPINE_VERSION` and `ALPINE_REGISTRY_BRANCH` if you intentionally
build for another Alpine branch, including `edge`.
Use `mise run gitea-workflow-build` for a local `pull_request` workflow check
through `act`; the publish step is skipped for that event.
## Test And Publish
Refresh generated sources through package-local hooks:
```sh
mise run apk:smoke
mise run apk:test-shell
mise run apk:publish-check
mise run apk:update-generated
ALPINE_PACKAGE=seaweedfs mise run apk:update-generated
mise run apk:checksum
```
`apk:publish-check` runs APKBUILD linting, rebuilds configured architectures,
lists package metadata, and installs the built packages in an Alpine container.
`apk:test-shell` builds the selected architecture, installs the local package
set in an Alpine container, and opens a shell. Use `SKIP_BUILD=1` to reuse an
existing local repository. Set `TEST_SHELL_TIMEOUT` to adjust the timeout for
`apk update` and `apk add` inside the test container.
Run `apk:checksum` after changing any file listed in `source=`.
Install from the local repo with the base package plus the role-specific OpenRC
subpackage you need:
### Gitea Workflow
```sh
apk add seaweedfs seaweedfs-master-openrc
```
The workflow at `.gitea/workflows/build.yml` builds in an `alpine:3.23`
container and publishes on push or tag. It skips publishing for pull request
events.
Optional generated material is split out:
```sh
apk add seaweedfs-doc
apk add bash-completion seaweedfs-bash-completion
```
The doc split installs upstream scaffolds under
`/usr/share/doc/seaweedfs/examples/`. The bash completion split installs
`/usr/share/bash-completion/completions/weed` and is also selected by
`install_if` when `seaweedfs` and `bash-completion` are installed together.
This repository publishes `seaweedfs`, matching Alpine aports. Remove Alpine's
old generic OpenRC package before installing a role split:
```sh
apk del seaweedfs-openrc
apk add seaweedfs seaweedfs-master-openrc
```
The OpenRC subpackages are:
Repository variables:
```text
seaweedfs-master-openrc -> seaweedfs.master
seaweedfs-volume-openrc -> seaweedfs.volume
seaweedfs-filer-openrc -> seaweedfs.filer
seaweedfs-s3-openrc -> seaweedfs.s3
seaweedfs-webdav-openrc -> seaweedfs.webdav
seaweedfs-sftp-openrc -> seaweedfs.sftp
seaweedfs-admin-openrc -> seaweedfs.admin
seaweedfs-worker-openrc -> seaweedfs.worker
INSTANCE_URL=https://code.factoring.digital
PACKAGE_OWNER=fsp-ops
PACKAGE_NAME=seaweedfs-alpine
```
Each service has defaults in `/etc/conf.d/seaweedfs.*`. Enable only the roles
needed on the node:
Repository secrets:
```text
PACKAGE_USER=<gitea package publisher>
PACKAGE_TOKEN=<token with package write access>
```
Pre-check the workflow locally with `act`:
```sh
rc-update add seaweedfs.master default
rc-service seaweedfs.master start
mise run gitea-workflow-build
```
If the repo key is missing on a target system, copy `.cache/abuild/*.rsa.pub`
into `/etc/apk/keys/` before `apk update`.
## Gitea Registry
The Gitea workflow reads these repository variables and secrets:
```text
Variables: INSTANCE_URL, PACKAGE_OWNER, PACKAGE_NAME
Secrets: PACKAGE_USER, PACKAGE_TOKEN
```
It uploads each built `*.apk` with HTTP `PUT` to:
```text
${INSTANCE_URL}/api/packages/${PACKAGE_OWNER}/alpine/v3.23/${PACKAGE_NAME}
```
For local publishing, run:
Publish already-built local packages manually:
```sh
INSTANCE_URL=https://code.factoring.digital \
@@ -150,21 +351,38 @@ PACKAGE_TOKEN=... \
mise run apk:publish-gitea
```
## Alpine Package Dos And Don'ts
### Alpine Package Rules
Do:
- Keep local `source` files next to the `APKBUILD`.
- Keep local package sources next to the `APKBUILD`.
- Put full upstream scaffolds in `/usr/share/doc/seaweedfs/examples/`, not active `/etc`.
- Run `mise run apk:update-generated` when updating generated examples or completions.
- Run `mise run apk:checksum` after changing any package source file.
- Install only the OpenRC role packages needed on each node.
- Keep `/etc/conf.d` defaults short and production-neutral.
- Increment `pkgrel` for package-only changes; reset it when `pkgver` changes.
- Keep installed defaults short and production-neutral.
- Run `mise run apk:publish-check` before handing off a repository.
- Run `mise run apk:publish-check` before opening a PR.
Don't:
- Edit generated `src/`, `pkg/`, or `packages/` output.
- Hand-edit checksum lines when `abuild checksum` can do it.
- Bundle long upstream examples as active `/etc` defaults.
- Install all OpenRC roles on a node by default.
- Hand-edit checksum lines when `abuild checksum` can update them.
- Install all OpenRC roles by default.
- Put long upstream examples into active `/etc` defaults.
### Practical PR Checklist
Before opening a PR, run:
```sh
mise run apk:publish-check
mise run gitea-workflow-build
mise run apk:test-install
```
Then test at least one installed role in the package shell:
```sh
mise run apk:test-shell
rc-service seaweedfs.master start
weed version
```