Set the global nix-path from the declarative NIX_PATH list so a clean environment resolves the same locked Nixpkgs. Keep old root channel profiles for recovery rather than deleting them to silence the activation warning.
86 lines
6.2 KiB
Markdown
86 lines
6.2 KiB
Markdown
# Development host
|
|
|
|
Flat, explicit NixOS modules, with locked inputs. Required machine setup belongs in these configs—not a list of manual installs or dotfile copies.
|
|
|
|
| File | Owns |
|
|
| --- | --- |
|
|
| `flake.nix`, `flake.lock` | Host entry point and exact Nixpkgs/Home Manager/dotfile revisions and content hashes |
|
|
| `configuration.nix` | EC2 base, platform, Nix features, compatibility version, imports |
|
|
| `users.nix` | `dev`, SSH/sudo, Home Manager integration, workspace/repo ownership |
|
|
| `dev-authorized-keys` | Public SSH keys for `dev`—never private keys |
|
|
| `tools.nix` | Git, declarative user Git policy, official Nix formatter |
|
|
| `neovim.nix` | Editor and deployment of the unchanged upstream dotfiles |
|
|
|
|
## Account
|
|
|
|
- Daily user: `dev`, UID 1001, home `/home/dev`, workspace `~/projects`.
|
|
- Passwordless sudo is scoped to `dev`; existing SSM-user administration and root SSH recovery remain intact.
|
|
- `dev` is authorized by the public key in this repo. No private key or password is embedded.
|
|
- `/etc/nixos` is writable by `dev` through a native tmpfiles ownership rule, which does not follow store symlinks.
|
|
- Nix daemon access stays untrusted for ordinary use. Sudo is a separate, explicit administrative capability.
|
|
- Bash is the temporary default; further shell/workflow preferences remain the user's choice.
|
|
|
|
Enter from an administrator session with `sudo -iu dev`.
|
|
|
|
Git author identity and remote destination are deliberately unset. `user.useConfigOnly` is now a Home Manager setting in `tools.nix`, not a required manual `git config` step.
|
|
|
|
## Build and apply
|
|
|
|
As `dev`, from `/etc/nixos`:
|
|
|
|
```sh
|
|
nixfmt --check ./*.nix
|
|
nix flake check --no-update-lock-file
|
|
nix build .#nixosConfigurations.dev.config.system.build.toplevel --no-update-lock-file
|
|
```
|
|
|
|
New source files must be added to Git for flakes to see them. Keep `flake.lock` in version control. A build does **not** activate changes.
|
|
|
|
Review and activate exactly the built closure:
|
|
|
|
```sh
|
|
built=$(readlink -f result)
|
|
sudo "$built/sw/bin/nixos-rebuild" dry-activate --no-reexec --store-path "$built"
|
|
sudo "$built/sw/bin/nixos-rebuild" switch --no-reexec --store-path "$built"
|
|
```
|
|
|
|
Use the rebuild tool from that closure with `--no-reexec`: otherwise the bootstrap tool can try to rebuild itself through the old channel even when `--store-path` is supplied. Capturing `built` also keeps review and activation on the same immutable result.
|
|
|
|
For initial deployment on a compatible NixOS EC2 base where flakes are not enabled yet, check out this repo and run the build as an existing administrator with the temporary CLI flag:
|
|
|
|
```sh
|
|
nix --extra-experimental-features 'nix-command flakes' build \
|
|
.#nixosConfigurations.dev.config.system.build.toplevel --no-update-lock-file
|
|
```
|
|
|
|
Then review/apply the resulting closure as above. The configuration creates `dev`, sets permissions and deploys its files. **No separate Neovim clone, copy, useradd, chown or global Git-config recipe is required.**
|
|
|
|
This host build does not use a mutable channel. NixOS's native flake integration pins the `nixpkgs` registry entry and login-shell `<nixpkgs>` lookup to the system input; the global `nix-path` setting keeps the same pin when `NIX_PATH` is unset. Old root channel profiles are retained for recovery, not used as build inputs. Dev-environment templates/composition remain deferred; there is no flake framework here.
|
|
|
|
## Neovim: import, do not rewrite
|
|
|
|
The input is [the existing neovim-dots repository](https://git.cyber.ayyalasomayajula.net/marsultor/neovim-dots), initially pinned to `380eb86778a7c53a0f1c18e84f14037456155347`.
|
|
|
|
Home Manager deploys its files under `~/.config/nvim`, with the **Lua, AstroNvim, Lazy, Mason, plugins and keymaps unchanged**. `programs.neovim.configure` stays empty so Neovim discovers `init.lua` normally. No Nixvim or custom Lua loader.
|
|
|
|
- Configuration files are linked from the pinned source and managed by Nix. Change the upstream repo and its input revision rather than editing generated links.
|
|
- Lazy's `lazy-lock.json` must remain writable. The config seeds a copy at `~/.local/state/nvim/locks/<dotfile-revision>.json` and links to it. A new dotfile revision gets its own original lock; repeated activation preserves runtime changes to an existing lock.
|
|
- A declared migration preserves the earlier manual checkout intact at `~/projects/neovim-dots-before-nix`. It refuses to overwrite an existing backup. On a clean home this migration does nothing.
|
|
|
|
**Reproducibility boundary:** Nix locks the host inputs and dotfile source, and reproduces their deployment. The existing Lua still bootstraps Lazy and manages plugin/Mason downloads at runtime. The supplied Lazy lock records plugin revisions, but it is writable and Mason's tool versions are not pinned by this Nix config. This is not a claim that every runtime download/cache is a Nix-reproducible build. Changing that policy requires a separate agreement; do not silently replace the user's plugin managers.
|
|
|
|
## Validation and commits
|
|
|
|
The initial deployment was tested with an empty disposable home: all upstream files were reproduced byte-for-byte, the Lazy lock remained writable across repeated activation, and the migration preserved local data and refused to overwrite an existing backup. The real plugin bootstrap is a separate runtime test, not covered by these file-deployment checks.
|
|
|
|
Make focused changes, format/evaluate them, and commit regularly. Build and activate a reviewed commit rather than accumulating uncommitted setup. `system.configurationRevision` records the source revision in the system generation. Do not put human identity guesses in Git settings or push to an unapproved remote.
|
|
|
|
## Updates and safety
|
|
|
|
- To change a pinned source, update its revision in `flake.nix`, regenerate `flake.lock` with `nix flake lock`, review the diff, then check/build before switching. No unattended updates.
|
|
- Keep the EC2 module, sandboxing, signature verification and recovery access intact.
|
|
- `system.stateVersion` and `home.stateVersion` are both `26.05`; these preserve compatibility, not package versions.
|
|
- `test` activates changes too; it is not a dry run. Keep the original system generation.
|
|
- Rollbacks do not restore mutable user/application data, lockfile updates, backups, or this Git working tree.
|
|
- No private keys, plaintext secrets, build outputs or agent notes in this repo.
|