92 lines
4.1 KiB
Markdown
92 lines
4.1 KiB
Markdown
# Memby Docker release builder
|
|
|
|
The `memby-builder` Compose service is an isolated Android toolchain. In the normal stack,
|
|
its small internal controller waits for the **Build latest release** button on Admin
|
|
Console → App updates. It then fetches the newest semantic `v*.*.*` tag from GitHub,
|
|
builds that exact source with its Gradle wrapper, signs it with Memby's existing release
|
|
identity, verifies it, and publishes it through the running gateway. Its port is exposed
|
|
only to the Compose network; the browser never receives its address or release token.
|
|
|
|
The image pins JDK 17, Android command-line tools 15859902, Android platform 35 and build
|
|
tools 35.0.0. Android SDK packages stay in the image layer; the `memby-gradle-cache` volume
|
|
persists Gradle distributions and dependencies between releases.
|
|
|
|
## One-time NAS setup
|
|
|
|
Set `MEMBY_SECRETS_DIR` in the deployment `.env` to an absolute directory that is outside
|
|
the directory replaced by `deploy-server.ps1`. The standard NAS value is:
|
|
|
|
```dotenv
|
|
MEMBY_SECRETS_DIR=/share/Docker/Memby-secrets
|
|
```
|
|
|
|
Create that directory with restrictive permissions and place these five files in it:
|
|
|
|
```text
|
|
/share/Docker/Memby-secrets/
|
|
memby-release.jks
|
|
memby-keystore-password
|
|
memby-key-alias
|
|
memby-key-password
|
|
memby-release-publish-token
|
|
```
|
|
|
|
- `memby-release.jks` must be the existing Memby release keystore. Do not generate a new
|
|
key: Android would reject it as an upgrade for every installed television.
|
|
- The three signing text files contain only their respective existing value, with no
|
|
`NAME=` prefix.
|
|
- `memby-release-publish-token` contains the existing gateway release-publish token. Move
|
|
that value out of `.env`; the gateway and builder now read the same Compose secret.
|
|
On the first upgraded deployment, `deploy-server.ps1` migrates this value automatically
|
|
when it is still present in the previous deployed `.env`. It never generates a new one.
|
|
|
|
Docker mounts all five files read-only under `/run/secrets`. Their values are never image
|
|
layers, source files, Compose environment values, Gradle arguments or `docker inspect`
|
|
output. `deploy-server.ps1` keeps the NAS directory at mode `0700` and its files read-only
|
|
at `0444`. The file mode is necessary because Compose file secrets are bind mounts and
|
|
both Memby containers run as non-root; the protected parent directory prevents other NAS
|
|
accounts from reaching those files.
|
|
|
|
## Create a release
|
|
|
|
Open Admin Console → App updates and press **Build latest release**. The page shows live
|
|
status and the retained build output. Leave the tag override blank for the latest GitHub
|
|
tag, or enter an exact semantic tag for a deliberate recovery build. A required release
|
|
has an extra confirmation because it blocks older televisions until they update.
|
|
|
|
If the console or controller is unavailable, use the command-line fallback from the
|
|
deployed Memby directory on the NAS:
|
|
|
|
```sh
|
|
docker compose run --rm --build memby-builder release
|
|
```
|
|
|
|
By default the builder queries `https://github.com/ponzischeme89/memby.git` and selects the
|
|
highest semantic tag. To reproduce a particular tagged release, set an explicit tag for
|
|
one invocation:
|
|
|
|
```sh
|
|
MEMBY_RELEASE_TAG=v0.2.64 docker compose run --rm --build memby-builder release
|
|
```
|
|
|
|
Optional, non-secret settings are listed with blank values in `builder.env.example`.
|
|
`MEMBY_RELEASE_MANDATORY=true` makes the published release mandatory; tests run unless
|
|
`MEMBY_SKIP_APP_TESTS=true` is deliberately set.
|
|
|
|
The final files are in the shared `memby-releases` Docker volume under `/data/releases`:
|
|
|
|
```text
|
|
/data/releases/memby-<version>.apk
|
|
/data/releases/memby-<version>.apk.sha256
|
|
```
|
|
|
|
Publishing through the gateway also updates its existing database-backed version,
|
|
download URL, release notes, size and SHA-256 metadata atomically. Every run checks the
|
|
application id and version, runs `apksigner verify --verbose --print-certs`, and compares
|
|
the APK signer digest with the certificate exported from the mounted keystore before the
|
|
gateway receives the APK.
|
|
|
|
The Windows `release.ps1`, `deploy-tv.ps1`, and the existing app-release option in
|
|
`deploy-server.ps1` remain available for local workflows and continue to use the same
|
|
signing identity.
|