NIX-CONFIG(7) Nix setup for Fedora Kinoite NIX-CONFIG(7)
00

DESCRIPTION

Fedora Kinoite is an atomic/immutable distro: the OS image is read-only and updated transactionally, while $HOME and the userland are yours to modify freely. This setup layers Nix + home-manager on top of that split to manage the userland declaratively, for two reasons:
  1. Keep multiple machines (laptop + desktop) in lockstep — same packages, same configs, same versions, all from one flake.
  2. Per-project development shells — Ruby/Node/Go versions and native libs (libpq, libyaml, libvips) flow in via per-project flakes without polluting global state.
Starting state assumed: a freshly-installed Fedora Kinoite. The eight numbered steps below take you from there to a working machine; §09 MAINTAIN covers ongoing sync.
01

PREPARE

Layered RPMs and transient root.

Add a [root] section to /etc/ostree/prepare-root.conf (use sudo $EDITOR) so the Nix installer can write to the root inode. Fresh Kinoite default:
[composefs]
enabled = yes
After your edit:
[composefs]
enabled = yes

[root]
transient = true
Layer the 1Password trio. App, CLI, and Chrome have to live on the host together: the browser extension talks to the app via Chrome's native-messaging hosts (paths under /etc/opt/chrome/native-messaging-hosts/), the CLI talks to the app over a Unix socket, and git signs commits via /opt/1Password/op-ssh-sign at a fixed absolute path. Flatpak sandboxing or Nix's FHS layout breaks each of those wires.
$sudo rpm-ostree install \
  1password 1password-cli google-chrome-stable
Layer the podman tooling on top of Kinoite's base podman: podman-docker aliases the docker CLI, podman-tui is a terminal UI for managing containers.
$sudo rpm-ostree install \
  podman-docker podman-tui
Track the prepare-root config so it survives ostree updates.
$sudo rpm-ostree initramfs-etc \
  --track=/etc/ostree/prepare-root.conf
Reboot to apply layered packages and the transient-root flag.
$sudo systemctl reboot
02

1PASSWORD

Install the 1Password desktop app and CLI, then enable the SSH agent. Every git push and ssh login that follows is signed by the agent.

Open the 1Password app, sign in with your account, and complete the first-run setup.
In 1Password: Settings → Developer → enable Use the SSH agent. Add at least one SSH key to your vault if you don't already have one.
List authorised SSH keys handed out by the 1Password agent.
$ssh-add -l
Confirm GitHub accepts the agent-signed key.
$ssh -T git@github.com
03

INSTALL

Determinate Nix in ostree mode.

Detects ostree + transient root, arranges nix.mount for /var/home/nix → /nix.
$curl --proto '=https' --tlsv1.2 -sSf -L \
  https://install.determinate.systems/nix \
  | sh -s -- install
Reboot so nix.mount and the daemon come up cleanly.
$sudo systemctl reboot
↻ After reboot, return here for the sanity check below.
Sanity check: version, mount, and a one-shot package run.
$nix --version \
  && mount | grep ' /nix ' \
  && nix run nixpkgs#hello
04

SUBSTITUTE

Pre-built Rubies from nixpkgs-ruby cachix.

Add the nixpkgs-ruby substituter so per-patch Rubies pull pre-built; without this each patch compiles from source (~5 min).
$sudo tee /etc/nix/nix.custom.conf <<'EOF'
extra-substituters = https://nixpkgs-ruby.cachix.org
extra-trusted-public-keys = nixpkgs-ruby.cachix.org-1:vrcdi50fTolOxWCZZkw0jakOnUI1T19oYJ+PRYdK4SM=
EOF
Restart the daemon so it picks up the new substituters.
$sudo systemctl restart nix-daemon
05

PURGE

Remove dotfiles HM is about to manage.

Drop shell rc files; HM refuses to clobber existing ones on first activation.
$rm -f ~/.bashrc ~/.bash_profile ~/.profile ~/.bash_logout
Drop tool configs HM will replace with managed symlinks.
$rm -f ~/.inputrc ~/.gitconfig ~/.gitignore ~/.vimrc ~/.npmrc
06

ACTIVATE

Fetch the flake. Build and switch the laptop profile.

Ensure ~/.config exists.
$mkdir -p ~/.config
Clone the flake into the path home-manager expects by default.
$git clone git@github.com:andreimaxim/nix-config.git \
  ~/.config/home-manager
Build and switch the laptop profile. First run pulls 2–4 GB; expect 5–20 min.
$nix run home-manager/master -- \
  init --switch \
  --flake ~/.config/home-manager#laptop
07

RELOGIN

Re-source the HM-managed environment.

End the session so the next login picks up HM-managed PATH and starts the podman quadlets.
$loginctl terminate-user $USER
08

VERIFY

Confirm the four quadlets are up and the dev tools resolve.

Confirm home-manager itself is installed.
$home-manager --version
Confirm git is signing commits via the 1Password SSH agent.
$git config --get gpg.ssh.program
Confirm all four podman quadlets are active.
$systemctl --user is-active \
  postgres16 redis mysql57 memcached
Confirm the dev tools resolve to ~/.nix-profile/bin/.
$which git fd rg jq vim claude
Rootless networking smoke-test — exercises the slirp4netns workaround.
$podman run --rm docker.io/library/alpine \
  wget -qO- https://example.com | head -c 100
Launch Zed once (app menu or zed in a terminal), then confirm the Vulkan ICD wrapper took effect.
$grep 'Selected GPU' ~/.local/share/zed/logs/Zed.log | head -1
Confirm the npm-globals activation hooks landed (herb-tools, ccusage, git-xor).
$ls ~/.local/bin | grep -E 'herb-|ccusage|git-xor'
09

MAINTAIN

Day-to-day sync; bump pinned inputs.

Pull the latest committed config and re-activate. Same command after editing the flake locally — drop the git pull.
$cd ~/.config/home-manager \
  && git pull \
  && home-manager switch --flake .#laptop
Bump nixpkgs and home-manager pins to the latest revisions. Commit the new flake.lock, then git pull on the other host.
$cd ~/.config/home-manager \
  && nix flake update \
  && home-manager switch --flake .#laptop
10

SEE ALSO