Manage packages with APM
Use apm to find, install, update, and remove software on your AOS host. Give
it package names; APM downloads the packages and installs the dependencies
they need to work.
In an AOS container, ordinary package installation also works in Dockerfile
RUN steps. File/configuration effects execute during installation; service
effects can remain pending until the selected init starts. See
packages in containers for the target handlers and lifecycle.
#Personal packages
By default, apm manages packages for your own account. Each user has a
separate package profile, so installing, upgrading, or removing your packages
does not change another user's selection. Users can keep different package
versions when needed.
For packages that contribute services, inspect the signed package contract and
selected resources described in Understand native package runtime
policy. Secure Boot and package trust
explains how image-baked registry anchors connect package admission to the boot
chain.
Package builds and their dependencies live in the shared /nix/store. Users
and the machine-wide profile reuse identical store paths instead of keeping
separate installed copies. Different versions or builds can coexist; each
profile selects the packages available in its environment. Registry metadata
and download caches remain separate for each scope.
Before using personal installs, ask your administrator to enable the multi-user
Nix daemon, authorize the package signing keys it accepts, and provision your
writable XDG directories and /var/lib/profiles/per-user/$USER profile. The
following commands assume that account setup is complete.
You do not need sudo for personal installs. APM asks the daemon to import
signed packages into the protected shared store, then updates your own profile.
The daemon checks signatures against administrator-configured keys; adding a
personal registry does not authorize its signing keys for the whole machine.
See Enable personal package installs for
administrator setup.
#Find packages
First refresh the package lists so APM knows what is available:
apm update
This downloads package information from your configured registries. It does not install or upgrade anything.
Search by name or description, then inspect a package:
apm search curl
apm show curl
Use apm policy curl to see available versions and their registries.
To add a registry or select a different source, see
Configure package registries.
#Install packages
Install a package by name:
apm install curl
You can install several packages in one command:
apm install curl jq
APM shows the planned changes and asks for confirmation. Dependencies are installed automatically. Installing named packages keeps unrelated packages already installed in your profile.
To review the plan without making changes, add --dry-run:
apm install curl --dry-run
To choose a particular registry, add --registry NAME. For unattended use,
--yes skips the confirmation prompt; review the plan before using it.
Installed programs are available on the login session's PATH, with your
personal packages ahead of machine-wide packages. To inspect
what is installed and which files a package supplies:
apm list --installed
apm files curl
apm depends curl
For packages that expose services, see
Understand the package sandbox and the package's generated
configuration reference, available through apm docs and apm options.
#Upgrade packages
Refresh the package lists, check which packages have newer versions, then upgrade:
apm update
apm list --upgradable
apm upgrade --dry-run
apm upgrade
upgrade uses the package lists you last downloaded; it does not refresh them
itself. To upgrade only selected packages, supply their names:
apm upgrade curl jq
To keep a package at its installed version during ordinary upgrades, hold it. Remove the hold when you are ready to upgrade it:
apm hold curl
apm held
apm unhold curl
These commands update runtime packages. To update the operating-system image,
use apm image upgrade as described in
Upgrade and roll back a host.
#Remove packages
Remove packages by name:
apm remove curl
APM checks whether installed packages still need them and shows the removal plan before asking for confirmation. Dependencies are kept unless you ask to remove those that are no longer needed:
apm autoremove
You can combine both operations:
apm remove curl --autoremove
Removing a package changes the active package set. Older package generations retain their files so that you can roll back. See Clean up old packages to reclaim their disk space.
#Reinstall or roll back packages
To download and install a package again:
apm reinstall curl
Package changes are recorded as numbered generations. List earlier package sets and preview a rollback:
apm rollback --list
apm rollback --generation N --dry-run
Replace N with a generation from the list, then apply it:
apm rollback --generation N
Without --generation, APM selects the previous package generation. Rollback
restores the package set, not application data such as databases. It does not
replace the running OS image or roll back host configuration.
#Clean up old packages
Keep the latest three personal package generations and the active generation:
apm clean --generations --keep 3
To reclaim unreferenced files from the shared store:
apm gc
Garbage collection works across the shared store. Files still referenced by another user's profile or a retained generation remain available.
#Prepare an image before selecting it
On a live AOS host, root can authenticate and stage a system image separately from choosing the next boot:
apm image prepare server --registry acme --dry-run
apm image prepare server --registry acme --yes
Preparation imports the signed closure, performs physical staging, and indexes
the authenticated receipt. It prints the exact staged ImageGeneration as JSON.
A dry-run resolves the package without importing, staging, or writing image
state. Preparation does not select the next boot or submit a rollout.
Add --qualified to require explicit authenticated candidate health before
staging for a later qualified rollout. This check does not itself qualify a
rollout; subsequent operator-source admission still applies. Pending profile or
image work must be recovered before preparing another candidate. Cancellation
waits for immutable transfers to finish before physical writes; interrupted
physical staging retains its intent for authenticated retry.
#Manage machine-wide packages
Administrators can add --system to manage packages for everyone on the
machine. Stock hosts support this workflow without personal account setup.
Find and install packages by name:
apm update --system
apm search nginx --system
apm install --system nginx curl --dry-run
apm install --system nginx curl
apm list --system --installed
The same package commands work in this scope:
apm upgrade --system --dry-run
apm upgrade --system
apm hold --system nginx
apm unhold --system nginx
apm remove --system nginx
apm autoremove --system
apm reinstall --system curl
apm rollback --system --list
apm rollback --system --generation N --dry-run
apm rollback --system --generation N
Run commands that change machine-wide packages as an administrator. These
operations change the runtime package set; use apm image for OS images and
apm config rollback for host configuration.
To clean machine-wide package and host configuration generations, then collect unreferenced store files and clean machine-wide registry overlays:
apm clean --system --generations --keep 3
apm gc --system
The active generations are retained. OS-image generations are not pruned, and store garbage collection still covers the shared store.
#Enable personal package installs
An administrator must install and enable the nix-daemon package before
regular accounts can import new packages into the shared store. Configure its
settings.allowed-users for the accounts permitted to connect and
settings.trusted-public-keys with the Nix package-signing public keys of your
approved caches. Keep settings.require-sigs enabled. Ordinary package users
need daemon access; they do not need membership in settings.trusted-users.
The daemon's client configuration selects it for new login shells. After setup,
log in again before using the personal commands above. The administrator must
also create each account's writable profile directory and XDG directories.
See apm docs show nix-daemon --system and
Configure an AOS host for package configuration.
#Apply a complete package set from a file
For repeatable provisioning, apply sets the complete desired package
set from a TOML file. This is optional; use install for everyday additions.
For example, save this as desired.toml:
packages = ["tailscale"]
Preview and apply it as an administrator:
apm update --system
apm apply --system --from ./desired.toml --dry-run
apm apply --system --from ./desired.toml
The file is the complete set of explicitly requested machine-wide packages. APM installs missing packages and their dependencies, removes explicitly installed packages omitted from the file, and removes dependencies that are no longer needed. Packages supplied by the base OS are managed separately. If you are editing an existing file, preserve every package you want to keep.
Keep every explicit package you want in this file when adding a workload.
Alternatively, host policy can
select a package with aos.apm.desiredPackages and configure its native service
in one generation, without a prior installation. Installing a payload alone
does not substitute for reviewing and enabling its service configuration.
The list is declarative. Explicit packages omitted from the next file are
removed during reconciliation, including packages made unreachable by that
change. To remove tailscale, delete it from packages and run the same command
again. Named package removal also accepts --system.
Reconciliation keeps an already-installed package rather than selecting a new
version. Use apm upgrade --system to upgrade installed packages. A dry run
uses cached package lists. When applying additions, reconciliation attempts a
refresh and warns if it must use cached metadata instead.
The desired file can also carry package configuration and credential inputs. APM validates them before changing the package profile. Prefer systemd system-credential references; protect any file containing credential bytes as secret state. See Manage secrets and Configure an AOS host for configuration and provisioning.
#Package state and trust
APM verifies packages against signed registry metadata before installation. See Configure package registries for sources and trust, and Secure Boot and package trust for measured-boot hosts.
The sysroot lock keeps runtime packages compatible with dependencies supplied
by the active OS image. Use --ignore-sysroot-lock only when a specific
recovery procedure requires it.
| State | Personal packages | Machine-wide packages |
|---|---|---|
| Profile | /var/lib/profiles/per-user/$USER | /var/lib/profiles/system |
| Registry clones | ~/.local/share/apm/registries | /var/lib/apm/registries |
| Package lists | ~/.local/share/apm/remote | /var/lib/apm/remote |
| Download cache | ~/.cache/apm | /var/lib/apm/cache |
| Writable trust pins | ~/.config/apm/trusted-keys.d | /var/lib/apm/trusted-keys.d |
Personal paths honor the corresponding XDG_* variables. Use apm --json ...
for automation; human-readable output is not a stable machine interface.
Host configuration has its own history under /var/lib/profiles/system,
managed with apm switch and apm config rollback. OS images have their own
history under /var/lib/profiles/image, managed with apm image. See
Upgrade and roll back a host for those operations.