feat: Add flake and ragenix package generation and dev environment
This commit is contained in:
264
FLAKE_SETUP.md
Normal file
264
FLAKE_SETUP.md
Normal file
@@ -0,0 +1,264 @@
|
||||
# USDA Vision - Nix Flake Setup
|
||||
|
||||
This directory now has a Nix flake for building and developing the USDA Vision system, with ragenix for managing secrets.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Development Environment
|
||||
|
||||
Enter the development shell with all tools:
|
||||
|
||||
```bash
|
||||
cd usda-vision
|
||||
nix develop
|
||||
```
|
||||
|
||||
This gives you:
|
||||
- Docker & Docker Compose
|
||||
- Node.js 20 with npm/pnpm
|
||||
- Python 3.11 with pip/virtualenv
|
||||
- Supabase CLI
|
||||
- Camera SDK (automatically in `LD_LIBRARY_PATH`)
|
||||
- ragenix for secrets management
|
||||
- All standard utilities (jq, yq, rsync, etc.)
|
||||
|
||||
### Building
|
||||
|
||||
Build the package:
|
||||
|
||||
```bash
|
||||
nix build
|
||||
# Or explicitly:
|
||||
nix build .#usda-vision
|
||||
```
|
||||
|
||||
Build just the camera SDK:
|
||||
|
||||
```bash
|
||||
nix build .#camera-sdk
|
||||
```
|
||||
|
||||
## Secrets Management with ragenix
|
||||
|
||||
### Initial Setup
|
||||
|
||||
1. **Generate or use an age key**:
|
||||
|
||||
```bash
|
||||
# Option 1: Generate a new age key
|
||||
mkdir -p ~/.config/age
|
||||
age-keygen -o ~/.config/age/keys.txt
|
||||
|
||||
# Option 2: Use your SSH key
|
||||
ssh-to-age < ~/.ssh/id_ed25519.pub
|
||||
# Copy the output to secrets/secrets.nix
|
||||
```
|
||||
|
||||
2. **Add your public key** to [secrets/secrets.nix](secrets/secrets.nix):
|
||||
|
||||
```nix
|
||||
{
|
||||
publicKeys = [
|
||||
"age1your_public_key_here"
|
||||
# or
|
||||
"ssh-ed25519 AAAA... user@host"
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
3. **Create encrypted environment files**:
|
||||
|
||||
```bash
|
||||
nix develop # Enter dev shell first
|
||||
ragenix -e secrets/env.age
|
||||
```
|
||||
|
||||
This opens your `$EDITOR` to edit the encrypted file. Add your environment variables:
|
||||
|
||||
```bash
|
||||
# Web environment (Vite)
|
||||
VITE_SUPABASE_URL=http://exp-dash:54321
|
||||
VITE_SUPABASE_ANON_KEY=your-anon-key-here
|
||||
# ... etc
|
||||
```
|
||||
|
||||
For Azure OAuth:
|
||||
|
||||
```bash
|
||||
ragenix -e secrets/env.azure.age
|
||||
```
|
||||
|
||||
### Using Secrets in Development
|
||||
|
||||
In the development shell, you can:
|
||||
|
||||
```bash
|
||||
# Edit secrets
|
||||
ragenix -e secrets/env.age
|
||||
|
||||
# View decrypted content (careful in shared screens!)
|
||||
age -d -i ~/.config/age/keys.txt secrets/env.age
|
||||
|
||||
# Re-encrypt all secrets after adding a new public key
|
||||
ragenix -r
|
||||
```
|
||||
|
||||
### Using Secrets in Production (NixOS)
|
||||
|
||||
The flake includes a NixOS module that handles secrets automatically:
|
||||
|
||||
```nix
|
||||
# In your NixOS configuration
|
||||
{
|
||||
inputs.usda-vision.url = "path:/path/to/usda-vision";
|
||||
|
||||
# ... in your module:
|
||||
imports = [ inputs.usda-vision.nixosModules.default ];
|
||||
|
||||
services.usda-vision = {
|
||||
enable = true;
|
||||
secretsFile = config.age.secrets.usda-vision-env.path;
|
||||
};
|
||||
|
||||
# Configure ragenix/agenix to decrypt the secrets
|
||||
age.secrets.usda-vision-env = {
|
||||
file = inputs.usda-vision + "/secrets/env.age";
|
||||
mode = "0644";
|
||||
owner = "root";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
usda-vision/
|
||||
├── flake.nix # Flake definition with outputs
|
||||
├── package.nix # Main application build
|
||||
├── camera-sdk.nix # Camera SDK build
|
||||
├── secrets.nix # ragenix configuration
|
||||
├── secrets/
|
||||
│ ├── secrets.nix # Public keys
|
||||
│ ├── env.age # Encrypted .env (safe to commit)
|
||||
│ ├── env.azure.age # Encrypted Azure config (safe to commit)
|
||||
│ └── README.md # Secrets documentation
|
||||
└── ... (rest of the app)
|
||||
```
|
||||
|
||||
## Migration from Old Setup
|
||||
|
||||
### Old Workflow
|
||||
- Manual `.env` file management
|
||||
- Secrets in plaintext (git-ignored)
|
||||
- Build defined in parent `default.nix`
|
||||
|
||||
### New Workflow
|
||||
- Encrypted `.age` files in git
|
||||
- Secrets managed with ragenix
|
||||
- Self-contained flake in `usda-vision/`
|
||||
- Development shell with all tools
|
||||
|
||||
### Migration Steps
|
||||
|
||||
1. **Encrypt existing `.env` files**:
|
||||
|
||||
```bash
|
||||
cd usda-vision
|
||||
nix develop
|
||||
|
||||
# Setup your age key first (see above)
|
||||
|
||||
# Encrypt the main .env
|
||||
ragenix -e secrets/env.age
|
||||
# Paste contents of old .env file, save and exit
|
||||
|
||||
# Encrypt Azure config
|
||||
ragenix -e secrets/env.azure.age
|
||||
# Paste contents of old .env.azure file, save and exit
|
||||
```
|
||||
|
||||
2. **Delete unencrypted files** (they're git-ignored but still local):
|
||||
|
||||
```bash
|
||||
rm .env .env.azure management-dashboard-web-app/.env
|
||||
```
|
||||
|
||||
3. **Commit encrypted secrets**:
|
||||
|
||||
```bash
|
||||
git add secrets/env.age secrets/env.azure.age secrets/secrets.nix
|
||||
git commit -m "Add encrypted secrets with ragenix"
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
### Security
|
||||
- ✅ Secrets encrypted at rest
|
||||
- ✅ Safe to commit to git
|
||||
- ✅ Key-based access control
|
||||
- ✅ Audit trail (git history)
|
||||
|
||||
### Development
|
||||
- ✅ Reproducible environment
|
||||
- ✅ All tools included
|
||||
- ✅ No manual setup
|
||||
- ✅ Version-locked dependencies
|
||||
|
||||
### Deployment
|
||||
- ✅ Declarative secrets management
|
||||
- ✅ Automatic decryption on NixOS
|
||||
- ✅ No manual key distribution
|
||||
- ✅ Clean integration with existing infrastructure
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Add a new developer
|
||||
|
||||
1. They generate an age key or use their SSH key
|
||||
2. They send you their public key
|
||||
3. You add it to `secrets/secrets.nix`
|
||||
4. Re-encrypt all secrets: `ragenix -r`
|
||||
5. Commit and push
|
||||
|
||||
### Rotate a secret
|
||||
|
||||
1. Edit the encrypted file: `ragenix -e secrets/env.age`
|
||||
2. Update the value
|
||||
3. Save and exit
|
||||
4. Commit: `git commit secrets/env.age -m "Rotate API key"`
|
||||
|
||||
### Build without flakes
|
||||
|
||||
If you need to build on a system without flakes enabled:
|
||||
|
||||
```bash
|
||||
nix-build -E '(import (fetchTarball https://github.com/edolstra/flake-compat/archive/master.tar.gz) { src = ./.; }).defaultNix.default'
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "error: getting status of '...': No such file or directory"
|
||||
|
||||
Make sure you're in the `usda-vision` directory when running `nix develop` or `nix build`.
|
||||
|
||||
### "cannot decrypt: no valid identity"
|
||||
|
||||
Your age private key isn't found. Check:
|
||||
- `~/.config/age/keys.txt` exists
|
||||
- Your public key is in `secrets/secrets.nix`
|
||||
- You've run `ragenix -r` after adding your key
|
||||
|
||||
### "experimental feature 'flakes' not enabled"
|
||||
|
||||
Add to `~/.config/nix/nix.conf`:
|
||||
```
|
||||
experimental-features = nix-command flakes
|
||||
```
|
||||
|
||||
Or run with: `nix --experimental-features 'nix-command flakes' develop`
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Nix Flakes](https://nixos.wiki/wiki/Flakes)
|
||||
- [ragenix](https://github.com/yaxitech/ragenix)
|
||||
- [age encryption](https://github.com/FiloSottile/age)
|
||||
Reference in New Issue
Block a user