Commit 8a62dc4f0b7f

Vincent Demeester <vincent@sbr.pm>
2026-08-12 10:27:17
fix(alpine): deref nix store symlinks for SELinux
Copied generated files into a temp dir instead of mounting /nix/store paths directly. SELinux enforcing blocks container access to the read-only nix store.
1 parent dd86966
Changed files (1)
alpine
alpine/build.sh
@@ -24,23 +24,24 @@ echo "==> Building Alpine appliance for $HOST (using $CONTAINER_ENGINE)"
 
 mkdir -p "$OUTPUT_DIR"
 
-# Resolve Nix store symlinks for generated files
-GENERATED_MOUNTS=""
-if [ -L "$SCRIPT_DIR/generated/zones" ]; then
-    REAL_ZONES=$(readlink -f "$SCRIPT_DIR/generated/zones")
-    GENERATED_MOUNTS="$GENERATED_MOUNTS -v $REAL_ZONES:$REAL_ZONES:ro"
+# Dereference Nix store symlinks into a temp dir so the container can
+# read them without needing /nix/store mounts (SELinux can't relabel the
+# read-only Nix store).
+GENERATED_TMP=$(mktemp -d)
+# ponytail: force-remove because :Z relabels files, making them owned by container sub-UIDs
+trap 'rm -rf "$GENERATED_TMP" 2>/dev/null || true' EXIT
+if [ -d "$SCRIPT_DIR/generated/zones" ]; then
+    cp -rL "$SCRIPT_DIR/generated/zones" "$GENERATED_TMP/zones"
 fi
-if [ -L "$SCRIPT_DIR/generated/wireguard" ]; then
-    REAL_WG=$(readlink -f "$SCRIPT_DIR/generated/wireguard")
-    GENERATED_MOUNTS="$GENERATED_MOUNTS -v $REAL_WG:$REAL_WG:ro"
+if [ -d "$SCRIPT_DIR/generated/wireguard" ]; then
+    cp -rL "$SCRIPT_DIR/generated/wireguard" "$GENERATED_TMP/wireguard"
 fi
 
 # Build inside Alpine container for aarch64
-# shellcheck disable=SC2086 # GENERATED_MOUNTS needs word splitting
 $CONTAINER_ENGINE run --rm \
     --platform linux/arm64 \
     -v "$SCRIPT_DIR":/build:Z \
-    $GENERATED_MOUNTS \
+    -v "$GENERATED_TMP":/build/generated:Z \
     -w /tmp \
     docker.io/library/alpine:3.23 \
     /build/build-inner.sh "$HOST"