# 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-.apk /data/releases/memby-.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.