# 7. Installing software This is the chapter that makes an atomic system make sense. It is also the thing Alloy is most opinionated about. On a normal distro there is one question: install it or not. Here there are three places software can live, and picking the right one is most of the skill. Alloy replaces "which tool" with one question: **how much of your machine should this software be able to reach?** ## The isolation dial | Level | Sees | Use it for | |---|---|---| | `host` | Your whole home directory, your devices, the session bus | Development toolchains, anything that must feel installed | | `workspace` | Its own private home, plus the directories you name | Running someone else's build, a package manager over untrusted code | | `sandboxed` | What a portal hands it: a file picker, permission-gated devices | Graphical apps you did not write | You pick the level. Alloy picks the implementation behind it: distrobox for `host`, podman directly for `workspace`, flatpak for `sandboxed`. The level is the stable interface, which is why the backend can change later without your boxes changing. **Be clear about what `workspace` is.** A rootless container with a bind mount limits blast radius. It is not a security boundary and Alloy will not call it one. `sandboxed` is the only level with a real isolation model behind it. ## Boxes alloy pkg box lists every box on the machine, including ones created outside Alloy with a bare `podman run` or a direct `flatpak install`. An inventory that hid those would be lying. Rows mark which boxes are declared (reproducible) and which are ad hoc (gone on a rebuild). From that tab you can start, stop, enter, remove, and export a box. **Entering** a box hands the terminal over to it, so the console tears itself down and comes back when you exit. **Exporting** puts a command from inside a box onto your host `PATH`, at `~/.local/bin`, which Fedora already searches. Running `rg` then runs it inside its box, in the right directory, starting the box first if it was stopped. An exported wrapper takes the plain name of the binary, so two boxes exporting `rg` would land on one file, and exporting something the host already has would put the box's copy ahead of the system one. Neither happens quietly: an export whose name is already taken is refused, and the message names the file or the host path in the way. Drop the name from that box's `export.bin`, or clear whatever holds it, and export again. ## Declaring boxes Boxes can be described in TOML, which makes them reproducible and syncable: ```toml [box.dev] level = "host" image = "registry.fedoraproject.org/fedora-toolbox:43" export = { bin = ["rg", "fd", "hx"] } [box.scratch] level = "workspace" image = "registry.fedoraproject.org/fedora-toolbox:43" mounts = ["~/code/thing"] [box.somegui] level = "sandboxed" app = "org.example.SomeApp" ``` `host` and `workspace` boxes take an `image`; a `sandboxed` box is one app, so it takes an `app`. ## Layering onto the base image The fourth option is putting a package into the operating system itself: rpm-ostree install This does not change the running system. It stages a new deployment that takes effect at the next boot. `alloy pkg install` shows what is layered and which rows are staged rather than active, which is the single most confusing thing about an atomic base and the reason that tab exists. Layer sparingly. Every layered package slows down every future image update, and a package you layer is one that has to keep resolving against a base that moves. If it can be a box, make it a box. Removing one is `rpm-ostree uninstall `, and it stages the removal the same way. Whatever you install, it arrives without its man page. The image is built with documentation excluded, which is the largest single thing that keeps it from being a quarter of a gigabyte bigger, and rpm gives no way to keep man pages while dropping the rest of `%doc`. Most tools answer `--help`; for the rest, upstream's own documentation is a search away. If you would rather have the pages, build your image with `TRIM=keep` (chapter 2) and they come back along with every translation. ## Sandboxed apps The `flatpak` client is in the image, no Flatpaks are provisioned, and **no remote is configured**. That last part is deliberate: a remote is a catalog, and a catalog is a decision about who your software comes from. Alloy does not make that one for you. So the first step is yours. Add whichever catalog you want: flatpak remote-add --user --if-not-exists Then apps install from it in the ordinary way: flatpak install org.example.SomeApp `alloy pkg` uses the same remotes; a box entry can name one, and one that does not is resolved across whatever you have added. Alloy ships no graphical file manager, so this is where one comes from if you want one. ## What a sandboxed app does not get Alloy trims flatpak's default permissions before an app ever asks. The image ships system-wide overrides that remove three grants: X11 access, raw access to every device node, and blanket access to your home directory and the host filesystem. GPU access stays, because a video player or a browser without it is not usable. That is a smaller sandbox than most catalogs assume, so some apps will misbehave. Give back what one actually needs, per app: flatpak override --user org.example.SomeApp --filesystem=~/Projects The list of what an app currently has: flatpak info --show-permissions org.example.SomeApp The defaults live in `/var/lib/flatpak/overrides/global`. It is yours to edit, and an image update will not overwrite it once it exists. ## X11 applications do not run There is no X server. Alloy is a Wayland-only session and the sway config ships `xwayland disable`, so an application that can only speak X11 exits saying it cannot open a display. This affects Steam, most Electron applications, some screen-sharing paths, and older Java toolkits. Anything Wayland-native is unaffected, and most Electron apps can be told to use Wayland with `--ozone-platform=wayland`. The reason is that X11 gives every client the ability to read every other client's keystrokes and window contents. A sandboxed app with X11 access is not sandboxed in any way that matters. If you need it back, put this in `~/.config/sway/config.d/` and log in again: xwayland enable Your file wins over the shipped one. The Xwayland package stays in the image so that this works without rebuilding. Turning it on is a real cost, not a formality: it applies to the whole session, not to the one app you wanted. ## Which one, in practice - **A CLI tool you use daily and Fedora has it.** Layer it, or put it in a `host` box and export it. Layering is simpler; the box keeps the base clean. - **A language toolchain for one project.** `workspace`, with the project directory mounted. - **A graphical app from the internet.** `sandboxed`. - **Something the desktop itself needs to work** (a compositor piece, a font, a daemon). Edit the Containerfile and rebuild. That is what the builder model is for.