docs: add standalone chezmoi bootstrap and gotchas
Document how to bring chezmoi up on another VPS without the provisioning layer, and record the chezmoi behaviours that caused real breakage here. The umask trap is the load-bearing one: chezmoi derives modes from the umask at apply time rather than preserving them, so the atuin key dir and config need both the private_ attribute and umask = 0o022 to land at 0700 and 0600. The apply-into-head SIGPIPE is the other: it truncates the apply and reports head's exit status, so a partial apply looks successful. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
75
README.md
75
README.md
@@ -29,6 +29,50 @@ Expect **10–20 minutes**: atuin, eza, macchina and oxker are built from source
|
||||
trade for matching the currently-running versions exactly rather than taking
|
||||
whatever apt ships.
|
||||
|
||||
## chezmoi on another VPS
|
||||
|
||||
`setup.sh` already does all of this. Use this path only when you want the dotfiles
|
||||
*without* the provisioning layer (no apt, no rust, no `chsh`) — e.g. a box where the
|
||||
tools are already there, or where you don't have root.
|
||||
|
||||
```bash
|
||||
# 1. install chezmoi (user-local, no root)
|
||||
sh -c "$(curl -fsLS get.chezmoi.io)" -- -b "$HOME/.local/bin"
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
# 2. pin the umask BEFORE the first apply — see Notes, this is load-bearing
|
||||
mkdir -p ~/.config/chezmoi
|
||||
printf 'umask = 0o022\n' >> ~/.config/chezmoi/chezmoi.toml
|
||||
|
||||
# 3. pull the source state (private repo — needs Gitea credentials)
|
||||
chezmoi init https://git.domverse-berlin.eu/domverse/dotfiles.git
|
||||
|
||||
# 4. look before you leap
|
||||
chezmoi diff
|
||||
|
||||
# 5. write it out
|
||||
chezmoi apply
|
||||
```
|
||||
|
||||
Notes on the above:
|
||||
|
||||
- **Step 2 must come before step 4.** The umask is read at apply time; applying
|
||||
first and fixing the config after leaves wrong modes on disk.
|
||||
- **Step 3 needs repo access.** The repo is private. Either have
|
||||
`credential.helper=store` already populated, or clone over SSH:
|
||||
`chezmoi init git@git.domverse-berlin.eu:domverse/dotfiles.git`.
|
||||
- The source clone lands in `~/.local/share/chezmoi` (chezmoi's default). This box
|
||||
is the exception — it sets `sourceDir = /home/crabix/projects/dotfiles` in
|
||||
`~/.config/chezmoi/chezmoi.toml` because the repo predates chezmoi. On a fresh
|
||||
box, don't set `sourceDir`; the default is what `setup.sh` expects.
|
||||
- `.chezmoiroot` contains `home`, so the source root is `home/`, not the repo root.
|
||||
`setup.sh` and `README.md` sit outside chezmoi's view by design.
|
||||
- If `~` already has real dotfiles, `chezmoi diff` in step 4 shows exactly what
|
||||
gets clobbered. Back them up with modes intact first:
|
||||
`cp -a ~/.config/fish ~/.config/atuin ~/backup/dotfiles-preapply-$(date -u +%Y%m%dT%H%M%SZ)/`
|
||||
- Then do the **Manual steps** below (atuin key, git identity) — they are not
|
||||
specific to `setup.sh`.
|
||||
|
||||
## Day-to-day
|
||||
|
||||
Configs are managed by chezmoi, so the file in `~/.config` is a *copy*, not a
|
||||
@@ -83,6 +127,37 @@ The script prints these; repeated here because they're easy to miss:
|
||||
```
|
||||
3. **Log out and back in** for the fish shell change to take effect.
|
||||
|
||||
## chezmoi gotchas
|
||||
|
||||
Learned the hard way while building this. Don't rediscover them.
|
||||
|
||||
- **chezmoi does not preserve file modes.** It tracks only the `executable_` and
|
||||
`private_` source attributes and derives the actual mode from the *umask at apply
|
||||
time*. With `umask 002` (the default for this user), `~/.config/atuin/` silently
|
||||
goes `0700` → `0775` and `config.toml` `0600` → `0664`. Correct modes need **both**
|
||||
halves:
|
||||
- the source attribute — `private_atuin/private_config.toml`, and
|
||||
- `umask = 0o022` in `~/.config/chezmoi/chezmoi.toml` (`setup.sh` writes this).
|
||||
|
||||
Always `chezmoi diff` before trusting a dotfiles repo on a new box; the mode lines
|
||||
are quiet and easy to scroll past.
|
||||
|
||||
- **Never pipe `chezmoi apply` into a truncating command.** `chezmoi apply --verbose |
|
||||
head -20` SIGPIPEs chezmoi partway through, leaving the apply **incomplete** — files
|
||||
sorting after the cutoff are never written. Worse, `$?` reports *head's* exit status
|
||||
(0), so it looks like it succeeded. Redirect to a file and read that instead:
|
||||
|
||||
```bash
|
||||
chezmoi apply --verbose > /tmp/apply.log 2>&1; echo "exit=$?"
|
||||
```
|
||||
|
||||
- **The file in `~` is a copy, not a symlink.** Editing `~/.config/fish/config.fish`
|
||||
directly gets silently clobbered on the next apply. Use `chezmoi edit`. The
|
||||
`fishconfig` alias points at `chezmoi edit` for exactly this reason.
|
||||
|
||||
- **`chezmoi init` on a box with existing dotfiles overwrites without asking** once
|
||||
you `apply`. `chezmoi diff` first, always.
|
||||
|
||||
## Notes
|
||||
|
||||
- `config.fish` aliases `cat` to `batcat` — on Ubuntu the bat binary really is
|
||||
|
||||
Reference in New Issue
Block a user