184 lines
7.0 KiB
Markdown
184 lines
7.0 KiB
Markdown
|
|
# PalladiumWallet — Reproducible Builds via Docker
|
|||
|
|
|
|||
|
|
This folder builds all three distribution targets — **Windows**, **Linux**,
|
|||
|
|
**Android** — inside Docker containers. The entire toolchain (.NET 10 SDK,
|
|||
|
|
JDK, Android SDK, android workload) lives in the container images, pinned in
|
|||
|
|
the Dockerfiles, so:
|
|||
|
|
|
|||
|
|
- **anyone can produce the official binaries** with a single command, on any
|
|||
|
|
Linux machine, without installing any SDK on the host;
|
|||
|
|
- **the toolchain never drifts**: every build uses exactly the same SDK
|
|||
|
|
versions, regardless of what is installed (or updated) on the host;
|
|||
|
|
- **the build environment is auditable**: the Dockerfiles in this folder are
|
|||
|
|
the complete, reviewable definition of how release binaries are made — which
|
|||
|
|
matters for a wallet, where users must be able to trust that the shipped
|
|||
|
|
binary comes from the published source.
|
|||
|
|
|
|||
|
|
> **Scope note:** this pins the *build environment*. Bit-for-bit identical
|
|||
|
|
> output across machines is a stronger property that .NET does not guarantee
|
|||
|
|
> by default (embedded timestamps, signing); if two builds of the same commit
|
|||
|
|
> differ, they differ only in those metadata, not in code.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Prerequisites
|
|||
|
|
|
|||
|
|
A Linux host (native, WSL2, or a VM) with **Docker Engine** installed and
|
|||
|
|
running. Nothing else — no .NET SDK, no JDK, no Android SDK.
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Check that Docker works:
|
|||
|
|
docker info
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
If Docker is missing, install it from <https://docs.docker.com/engine/install/>
|
|||
|
|
(or `sudo apt install docker.io` on Debian/Ubuntu). If `docker info` fails
|
|||
|
|
with a permission error, add yourself to the `docker` group and start a new
|
|||
|
|
shell:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo usermod -aG docker $USER
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Disk space:** ~2 GB for the desktop image, ~7 GB for the Android image
|
|||
|
|
(SDK + emulator-less toolchain). **First-run time:** the images are built
|
|||
|
|
automatically on first use — a few minutes for desktop, 10–20 minutes for
|
|||
|
|
Android (large downloads). Subsequent builds reuse the cached images and take
|
|||
|
|
well under a minute (desktop) / a few minutes (Android).
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Quick start
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# From the repository root (or from the docker/ folder — both work):
|
|||
|
|
./docker/build.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Running without arguments shows an interactive menu — pick a single target or
|
|||
|
|
`all`. Non-interactive usage:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
./docker/build.sh [TARGET] [--rebuild]
|
|||
|
|
|
|||
|
|
Targets:
|
|||
|
|
windows Win x64 single-file executable (native libs embedded)
|
|||
|
|
linux Linux x64 single-file binary (runs as-is, nothing to install)
|
|||
|
|
android Android APK (debug-signed)
|
|||
|
|
all All three targets
|
|||
|
|
|
|||
|
|
Options:
|
|||
|
|
--rebuild Force rebuild of the Docker images (needed after editing a Dockerfile)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Examples:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
./docker/build.sh all # build everything
|
|||
|
|
./docker/build.sh windows # Windows only
|
|||
|
|
./docker/build.sh android --rebuild # Android, rebuilding the image first
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Output — and how to use each artifact
|
|||
|
|
|
|||
|
|
All artifacts land in `dist/` at the repository root. The version number is
|
|||
|
|
read automatically from `<Version>` in `src/App/PalladiumWallet.App.csproj`.
|
|||
|
|
|
|||
|
|
| Target | Path |
|
|||
|
|
|---------|--------------------------------------------------|
|
|||
|
|
| Windows | `dist/windows/PalladiumWallet-{ver}-win-x64.exe` |
|
|||
|
|
| Linux | `dist/linux/PalladiumWallet-{ver}-linux-x64` |
|
|||
|
|
| Android | `dist/android/PalladiumWallet-{ver}.apk` |
|
|||
|
|
|
|||
|
|
**Windows** — a single self-contained `.exe` (runtime and native libraries
|
|||
|
|
embedded). Copy it to any 64-bit Windows 10/11 machine and double-click.
|
|||
|
|
The first launch takes a few extra seconds (it unpacks native libraries to a
|
|||
|
|
per-user cache); later launches are normal. SmartScreen may warn because the
|
|||
|
|
binary is not code-signed — choose "Run anyway".
|
|||
|
|
|
|||
|
|
**Linux** — a single self-contained binary, already executable. Copy and run:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
./PalladiumWallet-{ver}-linux-x64
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Works on any desktop distro with glibc, X11/Wayland and fontconfig (i.e.
|
|||
|
|
effectively all of them); no .NET or other packages to install. If you
|
|||
|
|
transfer it through a channel that strips permissions (e.g. a web download),
|
|||
|
|
restore the execute bit with `chmod +x`.
|
|||
|
|
|
|||
|
|
**Android** — a debug-signed APK for sideloading: transfer it to the phone
|
|||
|
|
and open it (enable "install from unknown sources" if prompted), or install
|
|||
|
|
via `adb install dist/android/PalladiumWallet-*.apk`. Supports Android 6.0+
|
|||
|
|
(API 23), arm64 phones and x86_64 emulators.
|
|||
|
|
|
|||
|
|
> **Signature caveat:** debug-signed APKs built on different machines carry
|
|||
|
|
> different keys. If a previous build is already installed, Android refuses
|
|||
|
|
> the update (`INSTALL_FAILED_UPDATE_INCOMPATIBLE`) — uninstall the old app
|
|||
|
|
> first. **Uninstalling deletes the app's data: back up the wallet seed
|
|||
|
|
> before doing this.** Release signing with a stable key is not set up yet.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## How it works
|
|||
|
|
|
|||
|
|
### Docker images
|
|||
|
|
|
|||
|
|
| Image | Dockerfile | Used for | Size |
|
|||
|
|
|---------------------|----------------------|-----------------|---------|
|
|||
|
|
| `plm-build-desktop` | `Dockerfile.desktop` | windows + linux | ~1.5 GB |
|
|||
|
|
| `plm-build-android` | `Dockerfile.android` | android | ~5 GB |
|
|||
|
|
|
|||
|
|
Images are built automatically the first time a target needs them and reused
|
|||
|
|
afterwards. Use `--rebuild` only after modifying a Dockerfile.
|
|||
|
|
|
|||
|
|
### Source isolation
|
|||
|
|
|
|||
|
|
The repository is mounted **read-only** inside the container; the build works
|
|||
|
|
on a copy at `/tmp/build`. Your working tree is never touched — no stray
|
|||
|
|
`bin/`/`obj/` directories, and a dirty working tree doesn't leak into the
|
|||
|
|
build beyond the files it contains. Artifacts are written back through a
|
|||
|
|
bind mount to `dist/` and chown'd to your user.
|
|||
|
|
|
|||
|
|
### NuGet cache
|
|||
|
|
|
|||
|
|
A Docker named volume `plm-nuget-cache` holds downloaded NuGet packages
|
|||
|
|
across builds. To reclaim the space or force a clean re-download:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
docker volume rm plm-nuget-cache
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Troubleshooting
|
|||
|
|
|
|||
|
|
- **`Docker daemon is not running`** — start it (`sudo systemctl start
|
|||
|
|
docker`; on WSL2, start Docker Desktop or the docker service).
|
|||
|
|
- **Android image build fails downloading `commandlinetools`** — Google
|
|||
|
|
rotates the build number in the URL. Update the URL in
|
|||
|
|
`Dockerfile.android` to the current one from
|
|||
|
|
<https://developer.android.com/studio#command-tools> and rerun with
|
|||
|
|
`--rebuild`.
|
|||
|
|
- **`error XA5207: Could not find android.jar for API level N`** — the .NET
|
|||
|
|
android workload moved to a newer API level. Bump
|
|||
|
|
`ANDROID_SDK_PLATFORM` (and `ANDROID_SDK_BUILD_TOOLS`) in
|
|||
|
|
`Dockerfile.android` to the level the error names, then `--rebuild`.
|
|||
|
|
- **APK won't install over an existing app** — signature mismatch between
|
|||
|
|
debug keys; see the signature caveat above.
|
|||
|
|
- **Everything is broken / start from scratch** —
|
|||
|
|
`docker system prune -a && docker volume rm plm-nuget-cache`, then rerun
|
|||
|
|
the script (images and packages are re-downloaded).
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Linux AppImage (future)
|
|||
|
|
|
|||
|
|
The Linux target currently produces a single-file self-contained binary.
|
|||
|
|
Once a `pupnet.conf` is added to the repository, the `build_linux` function
|
|||
|
|
in `build.sh` can be extended to call PupNet Deploy inside the same
|
|||
|
|
`plm-build-desktop` image to also produce an AppImage with desktop
|
|||
|
|
integration (icon, menu entry).
|