Skip to main content

max / alloy

Add a GUI dial, because no Alloy image has ever shipped webkit The four Tauri apps are built on fw13 and astra, and a stock mint carries no webkit at all -- rpm -qa | grep -i webkit is empty. So a build host minted without this looks healthy and fails at configure time on the first app it is asked for. The Debian-family distrobox in the migration plan had been hiding that: it carried the deps as a side effect of carrying an older glibc. Native rather than boxed, because the glibc question that justified the box is settled. Fedora 43 is glibc 2.42 against Ubuntu 24.04's 2.39, and cargo-tauri copies the WebKit libraries into the bundle while linuxdeploy excludes libc, so those copies meet the user's glibc. Max ruled on 2026-09-04 that a 2.42 floor is acceptable and backwards compatibility is not a goal. pkg-config is the assertion rather than the package list: a -devel set that installs cleanly and then fails at --exists is how this class fails. Weak deps stay on in this arm alone, against the file's usual rule, because a -devel package's recommends are the headers its dependents need. GUI=none asserts the set is absent, so a default mint is provably unchanged by the dial existing.
Author: Max Johnson <me@maxj.phd> · 2026-09-04 15:29 UTC
Signed with PGP, not checked
Commit: 23ebab6d7338cf210c85eb9055d1b87ef67f6a14
Parent: 410a8f2
3 files changed, +77 insertions, -1 deletion
M Containerfile +66 -1
@@ -942,6 +942,27 @@
942 942 # profile without changing anything here.
943 943 ARG DB=none
944 944
945 + # GUI is the system side of building a desktop app, and it is a dial for the
946 + # same reason DB is: a machine that ships one and a machine that builds one need
947 + # different things, and the difference should be a file rather than a memory.
948 + #
949 + # `tauri` installs the WebKitGTK development set the four Tauri apps compile
950 + # against. Alloy ships no webkit at all today -- `rpm -qa | grep -i webkit` is
951 + # empty on a stock mint -- so a build host without this dial fails at link time
952 + # on the first app it is asked to build, having looked healthy until then.
953 + #
954 + # THE GLIBC QUESTION THIS USED TO BE TANGLED WITH IS SETTLED. Until 2026-09-04
955 + # the plan was to build every AppImage inside a Debian-family distrobox, because
956 + # Fedora 43's glibc is 2.42 against Ubuntu 24.04's 2.39 and cargo-tauri copies
957 + # the WebKit libraries into the bundle while linuxdeploy excludes libc, so the
958 + # copies meet the user's glibc rather than the builder's. Max ruled that a 2.42
959 + # floor is acceptable and backwards compatibility is not a goal, which is what
960 + # makes a native build the answer and this dial the whole of it.
961 + #
962 + # Not gated on PROFILE, on the same reasoning as the language block: a build
963 + # host is a role rather than a profile, and astra is a server that builds.
964 + ARG GUI=none
965 +
945 966 # TRIM is the one builder choice about the *base* rather than about Alloy.
946 967 # fedora-bootc is a general-purpose server base, and three of the things it
947 968 # carries are unreachable from any Alloy install however the machine is used:
@@ -1009,6 +1030,10 @@
1009 1030 none|postgres16) ;; \
1010 1031 *) echo "unknown DB '$DB'; expected 'none' or 'postgres16'" >&2; exit 1 ;; \
1011 1032 esac; \
1033 + case "$GUI" in \
1034 + none|tauri) ;; \
1035 + *) echo "unknown GUI '$GUI'; expected 'none' or 'tauri'" >&2; exit 1 ;; \
1036 + esac; \
1012 1037 case "$TRIM" in \
1013 1038 unused|keep) ;; \
1014 1039 *) echo "unknown TRIM '$TRIM'; expected 'unused' or 'keep'" >&2; exit 1 ;; \
@@ -1017,7 +1042,7 @@
1017 1042 client:*|server:none) ;; \
1018 1043 server:*) echo "PROFILE=server ships no graphical session and cannot carry BROWSER=$BROWSER" >&2; exit 1 ;; \
1019 1044 esac; \
1020 - echo "building profile=$PROFILE browser=$BROWSER langs=${LANGS:-none} trim=$TRIM db=$DB"
1045 + echo "building profile=$PROFILE browser=$BROWSER langs=${LANGS:-none} trim=$TRIM db=$DB gui=$GUI"
1021 1046
1022 1047 # =====================================================================
1023 1048 # Install-time filtering: translations and documentation
@@ -2146,6 +2171,46 @@
2146 2171 esac; \
2147 2172 echo "db: $DB"
2148 2173
2174 + # =====================================================================
2175 + # The desktop-app build set, from the GUI choice.
2176 + #
2177 + # `ARG GUI` above argues why this is a dial. This is the Fedora spelling of the
2178 + # list goingson's README gives for Debian: webkit2gtk4.1-devel is the one that
2179 + # matters and the rest are what cargo-tauri and linuxdeploy reach for.
2180 + # libxdo-devel is the Fedora name for Debian's libxdo-dev, and
2181 + # libappindicator-gtk3-devel for libayatana-appindicator3-dev.
2182 + #
2183 + # Weak deps are left ON here, unlike every other install in this file. A -devel
2184 + # package's recommends are the headers and pkgconfig files its own dependents
2185 + # need, and dropping them produces a set that installs cleanly and then fails at
2186 + # `pkg-config --exists` for a library that is on disk. The cost is measured
2187 + # rather than assumed by the assertion below, which is the real gate: pkg-config
2188 + # has to find webkit2gtk-4.1, because that is what the Tauri build actually asks.
2189 + #
2190 + # No toolchain here. Rust arrives through LANGS and the Tauri CLI is a cargo
2191 + # install into $HOME, which is machine state; this arm is the system libraries
2192 + # and stops, the same way the database arm puts binaries on PATH and stops.
2193 + RUN set -eu; \
2194 + case "$GUI" in \
2195 + tauri) \
2196 + dnf install -y \
2197 + webkit2gtk4.1-devel gtk3-devel libsoup3-devel openssl-devel \
2198 + librsvg2-devel libappindicator-gtk3-devel libxdo-devel; \
2199 + dnf clean all; \
2200 + for mod in webkit2gtk-4.1 gtk+-3.0 libsoup-3.0 openssl librsvg-2.0; do \
2201 + pkg-config --exists "$mod" \
2202 + || { echo "GUI=tauri was asked for and pkg-config cannot find $mod; a Tauri build would fail at configure time" >&2; exit 1; }; \
2203 + done; \
2204 + echo "gui: tauri, webkit2gtk-4.1 $(pkg-config --modversion webkit2gtk-4.1)" \
2205 + ;; \
2206 + none) \
2207 + ! pkg-config --exists webkit2gtk-4.1 2>/dev/null \
2208 + || { echo "GUI=none and the webkit development set is in the image anyway" >&2; exit 1; }; \
2209 + echo "gui: none" \
2210 + ;; \
2211 + *) echo "unknown GUI '$GUI' reached the install arm; the validator did not run" >&2; exit 1 ;; \
2212 + esac
2213 +
2149 2214 # =====================================================================
2150 2215 # Printing — driverless only, and deliberately in its own layer.
2151 2216 #
@@ -17,3 +17,7 @@
17 17 # Reserved key, read by build/build-iso.sh and ignored by build/build-image.sh.
18 18 # Not a cross-build: astra builds its own medium, on aarch64 hardware.
19 19 ARCH=aarch64
20 +
21 + # astra builds the arm64 releases, so it needs the same desktop-app set fw13
22 + # does. See build/hosts/fw13.env for why this is native rather than boxed.
23 + GUI=tauri
@@ -17,3 +17,10 @@
17 17 # database nobody deploys. Binaries only: creating the cluster is the machine's
18 18 # business, not the image's.
19 19 DB=postgres16
20 +
21 + # The four Tauri apps are built here, and Alloy ships no webkit on a stock mint,
22 + # so a build host without this links against nothing on the first app it is
23 + # asked for. Native rather than through a Debian-family distrobox: Max ruled on
24 + # 2026-09-04 that a glibc 2.42 floor is acceptable and backwards compatibility
25 + # is not a goal, which retired the only reason the box existed.
26 + GUI=tauri