Files
komp_ac/packaging/appimage/README.md
2026-09-02 21:27:54 +02:00

132 lines
5.5 KiB
Markdown

# Combined Linux AppImage
This packaging layer keeps `server` and `client-gui2` independently buildable
and combines their release artifacts into one `x86_64` Linux AppImage. The
AppImage entry point starts the selected server build, waits for its local gRPC
port, runs the GUI, and terminates the server when the GUI exits.
With the `full-embed` server feature, the PostgreSQL installation, database,
dumps, JWT secret and server log are persistent and are not stored in the
read-only AppImage. By default they live under
`${XDG_DATA_HOME:-$HOME/.local/share}/komp_ac`. Set `KOMP_AC_DATA_DIR` to
override that root. A `full` build instead uses the external PostgreSQL settings
supplied through `RUST_DB_*` environment variables. Both modes create fresh
runtime Tantivy indexes under the application-data root; existing repository
indexes are never packaged.
## Build both and combine
The frontend dependencies must already be present in `client-gui2/node_modules`.
The build also requires Nix and Tauri's Linux build dependencies. It uses
`appimagetool` from `APPIMAGETOOL` or `PATH` when available, otherwise it reuses
Tauri's cached `linuxdeploy-plugin-appimage.AppImage`. It does not fetch or
install frontend dependencies.
```sh
packaging/appimage/build.sh ./KompAC.AppImage
```
This performs the existing builds independently:
1. `nix build '.?submodules=1#portable-server'`
2. `yarn tauri build --bundles appimage --features full-embed` in `client-gui2`
3. `assemble.sh` to add the portable server and supervisor to the GUI AppImage
The standalone server and GUI build processes remain available unchanged.
## Combine existing artifacts
Already-built artifacts can be combined without rebuilding either application.
The first argument may be either a completed GUI AppImage or Tauri's completed
`.AppDir` directory. When combining with an embedded server, the GUI artifact
must have been built with its `full-embed` feature so it can safely place local
dump files into the bundled server's dump directory:
```sh
packaging/appimage/assemble.sh \
client-gui2/src-tauri/target/release/bundle/appimage/komp_ac.AppDir \
result/bin/server \
embedded \
./KompAC.AppImage
```
The generated AppImage uses local embedded mode and binds gRPC only to
`127.0.0.1:50051`. Only one combined AppImage instance may run against a data
directory at a time.
## Debian production build from NixOS
`build-debian.sh` uses rootless Podman to build inside a Debian 12 userspace.
The host source is mounted read-only and copied into the temporary container.
Cargo and Yarn caches use named Podman volumes, so neither Cargo target files
nor frontend dependencies are written into the repository. The source snapshot
excludes build outputs, local environment files and generated runtime data such
as Tantivy indexes, dumps and embedded PostgreSQL data. It also omits profiling
captures, benchmark and mutation reports, old AppImages, frontend caches, logs,
and local editor or agent state. Cargo configuration, SQLx offline metadata,
migrations and all crate/frontend source inputs remain in the snapshot. The
container validates the completed snapshot and stops before compilation if a
known runtime, cache or private-data path survived the exclusions. Top-level
copying is allowlisted to workspace manifests, required crates, `client-gui2`
and the packaging layer, so unrelated future repository directories are omitted
by default.
The server feature is a required argument. Nothing implicitly chooses the
database implementation:
```sh
# One-click application with PostgreSQL embedded in the server binary
packaging/appimage/build-debian.sh full-embed
# GUI and server using a separately managed PostgreSQL instance
packaging/appimage/build-debian.sh full
```
The default embedded outputs are:
```text
debian-dist/KompAC-embedded-debian12-amd64.AppImage
debian-dist/bin/client-gui2
debian-dist/bin/server
```
`full-embed` runs `cargo build --release --package server --features
full-embed`; PostgreSQL 17.10.0 is embedded by `postgresql_embedded`. `full`
runs the same command with `--features full` and configures the AppImage launcher
for external database mode. OpenSSL is linked statically in both builds. The GUI
is built by Tauri inside Debian with its normal AppImage dependency collection.
An alternative output directory and filename may be supplied:
```sh
packaging/appimage/build-debian.sh \
full-embed \
/path/to/releases \
KompAC-0.8.48-debian12-amd64.AppImage
```
An external build needs its database connection when launched:
```sh
RUST_DB_USER=komp_ac \
RUST_DB_PASSWORD=secret \
RUST_DB_HOST=127.0.0.1 \
RUST_DB_PORT=5432 \
RUST_DB_NAME=komp_ac \
./debian-dist/KompAC-external-debian12-amd64.AppImage
```
The build requires network access for the Debian builder image, APT packages,
Rust crates, frontend packages, PostgreSQL's embedded archive and Tauri's
AppImage tooling. The named cache volumes are retained for later production
builds. They can be inspected with `podman volume ls`.
On NixOS, the host script uses `/etc/containers/containers.conf` when Podman's
vendor configuration below `/usr/share` is not readable. An explicitly supplied
`CONTAINERS_CONF` is always preserved. If `/usr/share/containers/seccomp.json`
is also unreadable, the script visibly passes `--security-opt
seccomp=unconfined` to the rootless build containers. Restore normal host
permissions with `sudo chmod 755 /usr/share` to retain seccomp isolation. The
same fallback disables automatic OCI hook discovery when its vendor directory
is unreadable; explicitly configured hook overrides are never replaced.