|
| 1 | +# GitHub Copilot Instructions |
| 2 | + |
| 3 | +This NixOS configuration repository uses **categorized hosts** with automated zero-touch installation. All commands use `justfile`. |
| 4 | + |
| 5 | +## Quick Reference |
| 6 | + |
| 7 | +### Essential Commands |
| 8 | + |
| 9 | +```bash |
| 10 | +just --list # List all commands |
| 11 | +just install <host> <cat> <ip> # Install new host (fully automated) |
| 12 | +just deploy <hostname> # Deploy configuration |
| 13 | +just deploy-all # Deploy to all hosts |
| 14 | +just check # Validate flake |
| 15 | +just fmt # Format Nix files |
| 16 | +just update # Update flake inputs |
| 17 | +just secrets # Edit encrypted secrets |
| 18 | +just knock <vps> # Port knock and SSH to VPS |
| 19 | +``` |
| 20 | + |
| 21 | +### Repository Structure |
| 22 | + |
| 23 | +``` |
| 24 | +flake.nix # Main flake, defines all hosts |
| 25 | +justfile # All commands (replaces Make/scripts) |
| 26 | +hosts/ |
| 27 | + categories/ # Category-specific configs |
| 28 | + laptops.nix # Full workstations |
| 29 | + vps.nix # Hardened cloud instances |
| 30 | + servers.nix # On-premises servers |
| 31 | + experiments.nix # Development/testing |
| 32 | + {category}/{hostname}/ # Individual host configs |
| 33 | +modules/ |
| 34 | + networking/ # Tailscale, firewall, port knocking |
| 35 | + system/ # Security modules |
| 36 | + users/ # Home Manager configs |
| 37 | +secrets/ # SOPS-encrypted secrets |
| 38 | +``` |
| 39 | + |
| 40 | +## Host Categories |
| 41 | + |
| 42 | +- **laptops** (bit, spark, hermes): Full workstation with desktop, dev tools, Docker |
| 43 | +- **vps** (vps-alpha, ...): Hardened minimal cloud with port knocking, auto-updates |
| 44 | +- **servers** (server-alpha, ...): On-premises with Docker, monitoring |
| 45 | +- **experiments** (test-vm, ...): Development with relaxed security |
| 46 | + |
| 47 | +## Adding a New Host |
| 48 | + |
| 49 | +**Automated (recommended):** |
| 50 | +```bash |
| 51 | +# Boot NixOS installer on target, then: |
| 52 | +just install spark laptops 192.168.1.100 |
| 53 | +# Wait ~15 min - completely hands-off |
| 54 | +``` |
| 55 | + |
| 56 | +**Manual:** |
| 57 | +1. Create `hosts/{category}/{hostname}/configuration.nix` |
| 58 | +2. Add to `flake.nix` nixosConfigurations using `mkHost` |
| 59 | +3. Add to `deploy.nodes` for remote deployment |
| 60 | + |
| 61 | +## Security Rules |
| 62 | + |
| 63 | +1. **Never hardcode secrets** - use SOPS encryption |
| 64 | +2. **All secrets via `just secrets`** - edit `secrets/common/secrets.yaml` |
| 65 | +3. **Port knocking for VPS** - sequences in `secrets/vps/knock-sequences.yaml` |
| 66 | +4. **Tailscale for all hosts** - use hostnames, not IPs |
| 67 | +5. **SSH key-only auth** - no passwords |
| 68 | +6. **Run `just check` before commit** - validates all configs |
| 69 | +7. **Format with `just fmt`** - before committing Nix files |
| 70 | + |
| 71 | +## Secrets Management |
| 72 | + |
| 73 | +```bash |
| 74 | +just secrets # Edit common secrets |
| 75 | +just secrets secrets/vps/knock-sequences.yaml # Edit VPS secrets |
| 76 | +just secrets-view <file> # View decrypted |
| 77 | +just secrets-update # Re-encrypt after adding host |
| 78 | +``` |
| 79 | + |
| 80 | +**All secrets encrypted with SOPS (GPG + age). Never commit unencrypted secrets.** |
| 81 | + |
| 82 | +## Common Patterns |
| 83 | + |
| 84 | +### Deploying Changes |
| 85 | + |
| 86 | +```bash |
| 87 | +vim hosts/laptops/spark/configuration.nix |
| 88 | +just deploy spark |
| 89 | +``` |
| 90 | + |
| 91 | +### Updating All Hosts |
| 92 | + |
| 93 | +```bash |
| 94 | +just update # Update flake inputs |
| 95 | +git commit -am "update flake" |
| 96 | +just deploy-all # Deploy everywhere |
| 97 | +``` |
| 98 | + |
| 99 | +### VPS Access (Port Knocking) |
| 100 | + |
| 101 | +```bash |
| 102 | +just knock vps-alpha # Knocks and opens SSH |
| 103 | +``` |
| 104 | + |
| 105 | +### Rollback |
| 106 | + |
| 107 | +```bash |
| 108 | +just rollback spark # Rollback to previous generation |
| 109 | +just generations spark # List all generations |
| 110 | +``` |
| 111 | + |
| 112 | +## Module Organization |
| 113 | + |
| 114 | +- **Common modules** in `hosts/common/default.nix` - affect ALL hosts |
| 115 | +- **Category configs** in `hosts/categories/` - affect all hosts in category |
| 116 | +- **Host configs** in `hosts/{category}/{hostname}/` - host-specific only |
| 117 | +- **Network modules** in `modules/networking/` - Tailscale, firewall, knockd |
| 118 | +- **User modules** in `modules/users/` - Home Manager configurations |
| 119 | + |
| 120 | +## Best Practices |
| 121 | + |
| 122 | +1. **Use category configs** for shared functionality within a category |
| 123 | +2. **Test with dry-run** before deploying: `just dry-run spark` |
| 124 | +3. **Validate before commit**: `just check && just fmt` |
| 125 | +4. **Use Tailscale names** for addressing (opaque, no IPs in code) |
| 126 | +5. **Per-host hardware-configuration.nix** is auto-generated |
| 127 | +6. **Category changes affect all hosts** in that category - test carefully |
| 128 | +7. **Common changes affect ALL hosts** - be extremely conservative |
| 129 | +8. **VPS hardening is intentional** - minimal packages, port knocking, kernel hardening |
| 130 | + |
| 131 | +## Troubleshooting |
| 132 | + |
| 133 | +```bash |
| 134 | +just check # Validate flake syntax |
| 135 | +just dry-run <host> # See what would change |
| 136 | +just rollback <host> # Rollback to previous generation |
| 137 | +just tailscale-status <host> # Check Tailscale connection |
| 138 | +just info <host> # System information |
| 139 | +ssh <host> 'journalctl -xe' # View system logs |
| 140 | +``` |
| 141 | + |
| 142 | +## Development Workflow |
| 143 | + |
| 144 | +```bash |
| 145 | +nix develop # Enter dev shell (has all tools) |
| 146 | +just check # Validate all configs |
| 147 | +just fmt # Format all Nix files |
| 148 | +just build <host> # Build without deploying |
| 149 | +``` |
| 150 | + |
| 151 | +## Documentation |
| 152 | + |
| 153 | +- `AGENTS.md` - Complete AI assistant reference |
| 154 | +- `docs/WORKFLOW.md` - Installation and deployment workflow |
| 155 | +- `docs/JUSTFILE_COMMANDS.md` - Full command reference |
| 156 | +- `docs/SOPS_GPG_SETUP.md` - Secrets management guide |
| 157 | +- `README.md` - Main repository documentation |
| 158 | + |
| 159 | +## Automated Installation Features |
| 160 | + |
| 161 | +The `just install` command does everything automatically: |
| 162 | +1. Generates age encryption key |
| 163 | +2. Partitions/formats disk |
| 164 | +3. Installs NixOS |
| 165 | +4. Deploys age key |
| 166 | +5. Fetches hardware config |
| 167 | +6. Creates host configuration |
| 168 | +7. Updates .sops.yaml |
| 169 | +8. Updates flake.nix |
| 170 | +9. Re-encrypts secrets |
| 171 | +10. Commits to git |
| 172 | +11. Deploys full config |
| 173 | + |
| 174 | +**Result: Fully configured system in ~15 minutes with zero manual steps.** |
| 175 | + |
| 176 | +## Key Files |
| 177 | + |
| 178 | +- `flake.nix` - Host definitions, uses `mkHost` helper |
| 179 | +- `justfile` - All commands (install, deploy, secrets, etc.) |
| 180 | +- `.sops.yaml` - SOPS encryption configuration (GPG + age keys) |
| 181 | +- `hosts/common/default.nix` - Shared config for ALL hosts |
| 182 | +- `hosts/categories/{category}.nix` - Category-specific configs |
| 183 | +- `secrets/common/secrets.yaml` - Encrypted common secrets (Tailscale authkey, etc.) |
| 184 | +- `secrets/vps/knock-sequences.yaml` - Encrypted port knock sequences |
| 185 | + |
| 186 | +## When Suggesting Code |
| 187 | + |
| 188 | +- Use `just` commands, not scripts or make |
| 189 | +- Respect host categories and their security levels |
| 190 | +- Never suggest hardcoding secrets |
| 191 | +- Always validate with `just check` |
| 192 | +- Format with `just fmt` |
| 193 | +- Test with `just dry-run` before deploying |
| 194 | +- Use Tailscale hostnames, not IPs |
| 195 | +- Maintain zero-touch installation automation |
| 196 | +- Follow DRY principle with `mkHost` helper |
| 197 | +- Keep VPS configs minimal and hardened |
0 commit comments