Skip to main content

max / alloy

7.0 KB · 173 lines History Blame Raw
1 # 7. Installing software
2
3 This is the chapter that makes an atomic system make sense. It is also the
4 thing Alloy is most opinionated about.
5
6 On a normal distro there is one question: install it or not. Here there are
7 three places software can live, and picking the right one is most of the skill.
8 Alloy replaces "which tool" with one question: **how much of your machine
9 should this software be able to reach?**
10
11 ## The isolation dial
12
13 | Level | Sees | Use it for |
14 |---|---|---|
15 | `host` | Your whole home directory, your devices, the session bus | Development toolchains, anything that must feel installed |
16 | `workspace` | Its own private home, plus the directories you name | Running someone else's build, a package manager over untrusted code |
17 | `sandboxed` | What a portal hands it: a file picker, permission-gated devices | Graphical apps you did not write |
18
19 You pick the level. Alloy picks the implementation behind it: distrobox for
20 `host`, podman directly for `workspace`, flatpak for `sandboxed`. The level is
21 the stable interface, which is why the backend can change later without your
22 boxes changing.
23
24 **Be clear about what `workspace` is.** A rootless container with a bind mount
25 limits blast radius. It is not a security boundary and Alloy will not call it
26 one. `sandboxed` is the only level with a real isolation model behind it.
27
28 ## Boxes
29
30 alloy pkg box
31
32 lists every box on the machine, including ones created outside Alloy with a
33 bare `podman run` or a direct `flatpak install`. An inventory that hid those
34 would be lying. Rows mark which boxes are declared (reproducible) and which are
35 ad hoc (gone on a rebuild).
36
37 From that tab you can start, stop, enter, remove, and export a box.
38
39 **Entering** a box hands the terminal over to it, so the console tears itself
40 down and comes back when you exit.
41
42 **Exporting** puts a command from inside a box onto your host `PATH`, at
43 `~/.local/bin`, which Fedora already searches. Running `rg` then runs it inside
44 its box, in the right directory, starting the box first if it was stopped.
45
46 An exported wrapper takes the plain name of the binary, so two boxes exporting
47 `rg` would land on one file, and exporting something the host already has would
48 put the box's copy ahead of the system one. Neither happens quietly: an export
49 whose name is already taken is refused, and the message names the file or the
50 host path in the way. Drop the name from that box's `export.bin`, or clear
51 whatever holds it, and export again.
52
53 ## Declaring boxes
54
55 Boxes can be described in TOML, which makes them reproducible and syncable:
56
57 ```toml
58 [box.dev]
59 level = "host"
60 image = "registry.fedoraproject.org/fedora-toolbox:43"
61 export = { bin = ["rg", "fd", "hx"] }
62
63 [box.scratch]
64 level = "workspace"
65 image = "registry.fedoraproject.org/fedora-toolbox:43"
66 mounts = ["~/code/thing"]
67
68 [box.somegui]
69 level = "sandboxed"
70 app = "org.example.SomeApp"
71 ```
72
73 `host` and `workspace` boxes take an `image`; a `sandboxed` box is one app, so
74 it takes an `app`.
75
76 ## Layering onto the base image
77
78 The fourth option is putting a package into the operating system itself:
79
80 rpm-ostree install <package>
81
82 This does not change the running system. It stages a new deployment that takes
83 effect at the next boot. `alloy pkg install` shows what is layered and which
84 rows are staged rather than active, which is the single most confusing thing
85 about an atomic base and the reason that tab exists.
86
87 Layer sparingly. Every layered package slows down every future image update,
88 and a package you layer is one that has to keep resolving against a base that
89 moves. If it can be a box, make it a box.
90
91 Removing one is `rpm-ostree uninstall <package>`, and it stages the removal the
92 same way.
93
94 Whatever you install, it arrives without its man page. The image is built with
95 documentation excluded, which is the largest single thing that keeps it from
96 being a quarter of a gigabyte bigger, and rpm gives no way to keep man pages
97 while dropping the rest of `%doc`. Most tools answer `--help`; for the rest,
98 upstream's own documentation is a search away. If you would rather have the
99 pages, build your image with `TRIM=keep` (chapter 2) and they come back along
100 with every translation.
101
102 ## Sandboxed apps
103
104 The `flatpak` client is in the image, no Flatpaks are provisioned, and **no
105 remote is configured**. That last part is deliberate: a remote is a catalog,
106 and a catalog is a decision about who your software comes from. Alloy does not
107 make that one for you.
108
109 So the first step is yours. Add whichever catalog you want:
110
111 flatpak remote-add --user --if-not-exists <name> <url>
112
113 Then apps install from it in the ordinary way:
114
115 flatpak install <name> org.example.SomeApp
116
117 `alloy pkg` uses the same remotes; a box entry can name one, and one that does
118 not is resolved across whatever you have added. Alloy ships no graphical file
119 manager, so this is where one comes from if you want one.
120
121 ## What a sandboxed app does not get
122
123 Alloy trims flatpak's default permissions before an app ever asks. The image
124 ships system-wide overrides that remove three grants: X11 access, raw access to
125 every device node, and blanket access to your home directory and the host
126 filesystem. GPU access stays, because a video player or a browser without it is
127 not usable.
128
129 That is a smaller sandbox than most catalogs assume, so some apps will misbehave. Give
130 back what one actually needs, per app:
131
132 flatpak override --user org.example.SomeApp --filesystem=~/Projects
133
134 The list of what an app currently has:
135
136 flatpak info --show-permissions org.example.SomeApp
137
138 The defaults live in `/var/lib/flatpak/overrides/global`. It is yours to edit,
139 and an image update will not overwrite it once it exists.
140
141 ## X11 applications do not run
142
143 There is no X server. Alloy is a Wayland-only session and the sway config ships
144 `xwayland disable`, so an application that can only speak X11 exits saying it
145 cannot open a display.
146
147 This affects Steam, most Electron applications, some screen-sharing paths, and
148 older Java toolkits. Anything Wayland-native is unaffected, and most Electron
149 apps can be told to use Wayland with `--ozone-platform=wayland`.
150
151 The reason is that X11 gives every client the ability to read every other
152 client's keystrokes and window contents. A sandboxed app with X11 access is not
153 sandboxed in any way that matters.
154
155 If you need it back, put this in `~/.config/sway/config.d/` and log in again:
156
157 xwayland enable
158
159 Your file wins over the shipped one. The Xwayland package stays in the image so
160 that this works without rebuilding. Turning it on is a real cost, not a
161 formality: it applies to the whole session, not to the one app you wanted.
162
163 ## Which one, in practice
164
165 - **A CLI tool you use daily and Fedora has it.** Layer it, or put it in a
166 `host` box and export it. Layering is simpler; the box keeps the base clean.
167 - **A language toolchain for one project.** `workspace`, with the project
168 directory mounted.
169 - **A graphical app from the internet.** `sandboxed`.
170 - **Something the desktop itself needs to work** (a compositor piece, a font, a
171 daemon). Edit the Containerfile and rebuild. That is what the builder model
172 is for.
173