UNPKG

@sebastienrousseau/dotfiles

Version:

The Trusted Shell Platform — Universal dotfiles managed by Chezmoi. Features Bash & Zsh for macOS, Linux & WSL. Rust modern tooling & enterprise-grade security.

284 lines (198 loc) 6.85 kB
--- render_with_liquid: false --- # Tutorial: Deploy to a Fleet Roll out `.dotfiles` across multiple workstations and verify they're in sync. ## Scenario You have three hosts: - **macbook-t2** — your MacBook (current host, already installed) - **surface-pro** — your Linux laptop (new install) - **geekom-a9** — your desktop NUC (new install) Goal: all three running identical `.dotfiles` with per-host customization, with auditable cross-host attestation. ## Step 1: Per-Host Install On each new host: ```sh bash -c "$(curl -fsSL https://raw.githubusercontent.com/sebastienrousseau/dotfiles/master/install.sh)" ``` During `chezmoi init`, answer with the host's preset: - Surface Pro → `machine = "surface-pro"` - Geekom A9 → `machine = "geekom-a9"` ## Step 2: Exchange Signing Keys Each host has its own SSH ED25519 key. To verify commits and attestations across the fleet, publish each host's public key to every other host. **On each host, copy the public key:** ```sh cat ~/.ssh/id_ed25519.pub # ssh-ed25519 AAAAC3N...jkl5 user@macbook-t2 ``` **Collect all three keys. Append them to `~/.ssh/allowed_signers` on every host:** ``` user@macbook-t2 ssh-ed25519 AAAAC3N...jkl5 user@surface-pro ssh-ed25519 AAAAC3N...abc7 user@geekom-a9 ssh-ed25519 AAAAC3N...def9 ``` Optionally commit `allowed_signers` as a template so all hosts receive updates via `dot update`: ```sh # On macbook-t2 chezmoi add ~/.ssh/allowed_signers git add -A && git commit -sS -m "feat(ssh): add fleet signing keys" git push ``` Now every other host gets the updated list on `dot update`. ## Step 3: Share the Age Key (for Shared Secrets) If you want shared secrets decrypted on all three hosts, each host must have an Age key recipient in `.sops.yaml`. Option A: Share one key across all hosts (simpler, less granular). Option B: Each host has its own key; all three are listed as recipients (better operational security). For Option B: ```sh # On macbook-t2 (already set up) grep "public key:" ~/.config/age/keys.txt # On surface-pro age-keygen -o ~/.config/age/keys.txt grep "public key:" ~/.config/age/keys.txt # On geekom-a9 age-keygen -o ~/.config/age/keys.txt grep "public key:" ~/.config/age/keys.txt ``` Add all three public keys to `.sops.yaml`: ```yaml creation_rules: - path_regex: \.sops\.yaml$ age: >- age1aaa...111, # macbook-t2 age1bbb...222, # surface-pro age1ccc...333 # geekom-a9 ``` Re-encrypt existing secrets for the new recipients: ```sh # On macbook-t2 find . -name '*.sops.yaml' -exec sops updatekeys {} \; git add .sops.yaml dot_config/*.sops.yaml git commit -sS -m "chore(secrets): add fleet recipients" git push ``` Other hosts on `dot update` decrypt with their own private key automatically. ## Step 4: Verify Fleet Alignment From any host: ```sh dot fleet attest ``` Expected output: ``` Fleet Attestation — v0.2.501 Host Git SHA Policy Tools OK Drift Verified -------------- ---------- --------- ---------- ------- -------- macbook-t2 abc123d 0x7f2a… ✓ 0 ✓ surface-pro abc123d 0x7f2a… ✓ 0 ✓ geekom-a9 abc123d 0x7f2a… ✓ 0 ✓ -------------- ---------- --------- ---------- ------- -------- FLEET STATUS: 3/3 aligned ``` If any row shows drift or missing verification: ```sh # Check which host is out of sync dot fleet diff # SSH into the affected host and fix ssh surface-pro dot doctor && dot heal dot update ``` ## Step 5: Per-Host Customization Each host has its own `~/.config/chezmoi/chezmoi.toml` — use it for things that shouldn't propagate: ```toml # surface-pro's chezmoi.toml [data] machine = "surface-pro" theme = "dome-dark" # per-host default default_shell = "fish" terminal_font_size = 11 # smaller for HiDPI ``` ```toml # geekom-a9's chezmoi.toml [data] machine = "geekom-a9" theme = "valley-dark" # different default default_shell = "zsh" terminal_font_size = 14 # larger for external 1440p ``` Both hosts render from the same templates, producing correct platform-appropriate output. ## Step 6: Fleet-Wide Updates When you push a commit to master, each host pulls independently: ```sh # On each host dot update ``` `dot update` does: 1. `git pull --rebase --autostash` in `~/.dotfiles` 2. `chezmoi apply` with progress output 3. `dot heal` if apply detected drift 4. Reports changes applied For simultaneous update across the fleet (requires SSH): ```sh dot fleet sync # Connects to each host in parallel # Runs `dot update` via SSH # Collects outcomes ``` ## Step 7: Secrets Rotation When a secret is compromised (or as part of routine rotation): ```sh # 1. Edit the secret on any host sops dot_config/credentials.sops.yaml # Change the compromised value, save # 2. Commit and push git commit -sS -am "chore(secrets): rotate stripe key" git push # 3. All fleet hosts pick up the new value on next update # On each host: dot update ``` Since hosts all have the Age private key for themselves, decryption is automatic. ## Step 8: Decommission a Host When retiring a host: ```sh # 1. Remove the host's public key from allowed_signers # Edit dot_ssh/allowed_signers.tmpl (on any host) # 2. Remove the host's Age public key from .sops.yaml # 3. Re-encrypt all SOPS files (remove the decommissioned recipient) find . -name '*.sops.yaml' -exec sops updatekeys {} \; # 4. Commit git commit -sS -am "chore(fleet): decommission geekom-a9" git push # 5. On the decommissioned host: wipe the dotfiles state rm -rf ~/.dotfiles ~/.local/bin/dot ~/.config/chezmoi ~/.config/age ``` ## Troubleshooting ### "Fleet host unreachable" `dot fleet` couldn't SSH to a host. Check: ```sh ssh surface-pro 'dot version' # If this fails, fix SSH connectivity first ``` ### Drift on One Host Run `dot heal` on that host: ```sh ssh surface-pro 'dot heal' ``` If drift persists: ```sh ssh surface-pro 'chezmoi diff | head -50' # Inspect what's different ``` ### Policy Hash Mismatch One host has an older policy than the others. Usually means that host missed an update: ```sh ssh surface-pro 'dot update' ``` ### Attestation Signature Failed The host's SSH key isn't in `~/.ssh/allowed_signers` on the verifying host. Fix by redistributing `allowed_signers`. ## Summary A three-host fleet: - Installs from one repository - Has independent signing keys (each host verifies commits from others) - Can share secrets across specific hosts via SOPS recipients - Is auditable via `dot fleet attest` - Updates independently with `dot update` (or in parallel with `dot fleet sync`) ## Next - [Concept: Fleet Architecture](../01-concepts/04-fleet.md) - [Reference: Fleet Commands](../03-reference/01-dot-cli.md#fleet) - [Operations: Fleet Deployment](../../architecture/fleet-deployment.md)