docs: update zellij-ps to reflect project switcher functionality
- Update package description and fix mainProgram typo - Rewrite documentation to describe project switching, not process viewing - Add PROJECT_FOLDERS configuration and usage examples - Update all references across docs (README, guides, module overviews)
This commit is contained in:
493
docs/guides/adding-packages.md
Normal file
493
docs/guides/adding-packages.md
Normal file
@@ -0,0 +1,493 @@
|
||||
# Adding Packages Guide
|
||||
|
||||
How to add new packages to m3ta-nixpkgs.
|
||||
|
||||
## Overview
|
||||
|
||||
Packages in m3ta-nixpkgs are organized using a `callPackage` registry pattern. Each package lives in its own directory and is registered centrally.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Using Templates
|
||||
|
||||
Use the package template for quick setup:
|
||||
|
||||
```bash
|
||||
nix flake init -t .#package my-new-package
|
||||
```
|
||||
|
||||
This creates a template structure in `templates/package/` that you can copy.
|
||||
|
||||
### Manual Setup
|
||||
|
||||
1. Create directory: `pkgs/your-package/`
|
||||
2. Write `default.nix` with package definition
|
||||
3. Register in `pkgs/default.nix`
|
||||
|
||||
## Package Structure
|
||||
|
||||
```
|
||||
pkgs/your-package/
|
||||
├── default.nix # Package definition (required)
|
||||
├── source.py # Optional: additional source files
|
||||
├── wrapper.sh # Optional: wrapper scripts
|
||||
└── README.md # Optional: package documentation
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Rust Package
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
rustPlatform,
|
||||
fetchFromGitHub,
|
||||
}:
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "my-rust-app";
|
||||
version = "1.0.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "author";
|
||||
repo = "my-rust-app";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
|
||||
cargoLock.lockFile = src + "/Cargo.lock";
|
||||
|
||||
buildInputs = [openssl];
|
||||
|
||||
nativeBuildInputs = [pkg-config];
|
||||
|
||||
meta = with lib; {
|
||||
description = "My Rust application";
|
||||
homepage = "https://github.com/author/my-rust-app";
|
||||
license = licenses.mit;
|
||||
platforms = platforms.linux;
|
||||
mainProgram = "my-rust-app";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Python Package
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
python3,
|
||||
fetchFromGitHub,
|
||||
}:
|
||||
python3.pkgs.buildPythonPackage rec {
|
||||
pname = "my-python-app";
|
||||
version = "1.0.0";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "author";
|
||||
repo = "my-python-app";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
|
||||
build-system = with python3.pkgs; [setuptools];
|
||||
|
||||
dependencies = with python3.pkgs; [
|
||||
requests
|
||||
click
|
||||
];
|
||||
|
||||
optional-dependencies = with python3.pkgs; {
|
||||
extras = [pyyaml];
|
||||
};
|
||||
|
||||
doCheck = true;
|
||||
|
||||
pythonImportsCheck = ["myapp"];
|
||||
|
||||
meta = with lib; {
|
||||
description = "My Python application";
|
||||
homepage = "https://github.com/author/my-python-app";
|
||||
license = licenses.mit;
|
||||
platforms = platforms.linux;
|
||||
mainProgram = "my-app";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Shell Script Package
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
writeShellScriptBin,
|
||||
}:
|
||||
writeShellScriptBin "my-script" ''
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "Hello from my script!"
|
||||
|
||||
# Your script logic here
|
||||
''
|
||||
|
||||
# If you need to add dependencies
|
||||
{
|
||||
lib,
|
||||
writeShellApplication,
|
||||
bash,
|
||||
curl,
|
||||
}:
|
||||
writeShellApplication {
|
||||
name = "my-script";
|
||||
runtimeInputs = [bash curl];
|
||||
text = ''
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
curl -s https://example.com
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
### AppImage Package
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
appimageTools,
|
||||
fetchurl,
|
||||
}:
|
||||
appimageTools.wrapType2 rec {
|
||||
name = "my-app";
|
||||
version = "1.0.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/author/my-app/releases/download/v${version}/My-App-${version}.AppImage";
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
description = "My AppImage application";
|
||||
homepage = "https://github.com/author/my-app";
|
||||
license = licenses.unfree;
|
||||
platforms = platforms.linux;
|
||||
mainProgram = name;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Custom Source with Patch
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
fetchpatch,
|
||||
buildGoModule,
|
||||
}:
|
||||
buildGoModule rec {
|
||||
pname = "my-go-app";
|
||||
version = "1.0.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "author";
|
||||
repo = "my-go-app";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Add local patch
|
||||
./fix-build.patch
|
||||
|
||||
# Add patch from URL
|
||||
(fetchpatch {
|
||||
url = "https://github.com/author/my-app/pull/123.patch";
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
})
|
||||
];
|
||||
|
||||
vendorHash = "sha256-BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=";
|
||||
|
||||
meta = with lib; {
|
||||
description = "My Go application";
|
||||
homepage = "https://github.com/author/my-go-app";
|
||||
license = licenses.mit;
|
||||
platforms = platforms.linux;
|
||||
mainProgram = "my-app";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Package with Custom Installation
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
makeWrapper,
|
||||
}:
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "my-app";
|
||||
version = "1.0.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "author";
|
||||
repo = "my-app";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [makeWrapper];
|
||||
|
||||
buildPhase = ''
|
||||
make build
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
install -Dm755 my-app $out/bin/my-app
|
||||
|
||||
# Wrap with runtime dependencies
|
||||
wrapProgram $out/bin/my-app \
|
||||
--prefix PATH : ${lib.makeBinPath [some-dep]}
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "My custom application";
|
||||
homepage = "https://github.com/author/my-app";
|
||||
license = licenses.mit;
|
||||
platforms = platforms.linux;
|
||||
mainProgram = "my-app";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Registration
|
||||
|
||||
### Register in `pkgs/default.nix`
|
||||
|
||||
Add your package to the registry:
|
||||
|
||||
```nix
|
||||
{
|
||||
inherit (pkgs) callPackage;
|
||||
} rec {
|
||||
# Existing packages
|
||||
code2prompt = callPackage ./code2prompt {};
|
||||
zellij-ps = callPackage ./zellij-ps {};
|
||||
|
||||
# Your new package
|
||||
my-new-package = callPackage ./my-new-package {};
|
||||
}
|
||||
```
|
||||
|
||||
### With Custom Arguments
|
||||
|
||||
If your package needs custom arguments:
|
||||
|
||||
```nix
|
||||
# pkgs/default.nix
|
||||
{
|
||||
inherit (pkgs) callPackage;
|
||||
} rec {
|
||||
my-new-package = callPackage ./my-new-package {
|
||||
customArg = "value";
|
||||
};
|
||||
}
|
||||
|
||||
# pkgs/my-new-package/default.nix
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchurl,
|
||||
customArg, # This will be passed from the registry
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
## Getting Hashes
|
||||
|
||||
### Using `lib.fakeHash`
|
||||
|
||||
During development, use `lib.fakeHash` to get the real hash:
|
||||
|
||||
```nix
|
||||
src = fetchFromGitHub {
|
||||
owner = "author";
|
||||
repo = "my-app";
|
||||
rev = "v${version}";
|
||||
hash = lib.fakeHash; # Temporary placeholder
|
||||
};
|
||||
```
|
||||
|
||||
Build the package:
|
||||
|
||||
```bash
|
||||
nix build .#my-new-package
|
||||
```
|
||||
|
||||
Copy the actual hash from the error message and update the package:
|
||||
|
||||
```nix
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Real hash
|
||||
```
|
||||
|
||||
**Important**: Never commit `lib.fakeHash` to the repository.
|
||||
|
||||
## Testing
|
||||
|
||||
### Build Package
|
||||
|
||||
```bash
|
||||
nix build .#my-new-package
|
||||
```
|
||||
|
||||
### Test Execution
|
||||
|
||||
```bash
|
||||
nix run .#my-new-package -- --help
|
||||
```
|
||||
|
||||
### Run in Shell
|
||||
|
||||
```bash
|
||||
nix shell .#my-new-package
|
||||
my-new-app --version
|
||||
```
|
||||
|
||||
### Linting
|
||||
|
||||
```bash
|
||||
nix develop
|
||||
statix check pkgs/my-new-package/
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Meta Fields
|
||||
|
||||
Always include complete `meta` information:
|
||||
|
||||
```nix
|
||||
meta = with lib; {
|
||||
description = "Short one-line description";
|
||||
longDescription = ''
|
||||
Longer description explaining what the package does,
|
||||
its features, and use cases.
|
||||
'';
|
||||
homepage = "https://github.com/author/repo";
|
||||
changelog = "https://github.com/author/repo/releases/tag/v${version}";
|
||||
license = licenses.mit;
|
||||
platforms = platforms.linux;
|
||||
mainProgram = "program-name";
|
||||
};
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
Explicitly declare all dependencies:
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
# Runtime dependencies
|
||||
openssl,
|
||||
curl,
|
||||
# Native build dependencies
|
||||
pkg-config,
|
||||
cmake,
|
||||
}:
|
||||
```
|
||||
|
||||
### Versioning
|
||||
|
||||
Use `rec` to reference `version` in multiple places:
|
||||
|
||||
```nix
|
||||
rec {
|
||||
pname = "my-app";
|
||||
version = "1.0.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
rev = "v${version}";
|
||||
# ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Platform Restrictions
|
||||
|
||||
If package is platform-specific:
|
||||
|
||||
```nix
|
||||
meta = with lib; {
|
||||
# Linux only
|
||||
platforms = platforms.linux;
|
||||
|
||||
# Or specific platforms
|
||||
platforms = ["x86_64-linux" "aarch64-linux"];
|
||||
|
||||
# Or exclude platforms
|
||||
broken = stdenv.isDarwin;
|
||||
};
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Hash Mismatch
|
||||
|
||||
Error: `got: sha256-AAAAAAAA... expected: sha256-BBBBBB...`
|
||||
|
||||
Solution: Copy `got` hash and update package definition.
|
||||
|
||||
### Dependency Not Found
|
||||
|
||||
Error: `error: undefined variable 'somedep'`
|
||||
|
||||
Solution: Add dependency to function arguments and build inputs:
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
somedep, # Add here
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
buildInputs = [somedep]; # Add here
|
||||
}
|
||||
```
|
||||
|
||||
### Import Check Failure
|
||||
|
||||
Error: `error: Python module 'mymodule' not found`
|
||||
|
||||
Solution: Disable or fix imports check:
|
||||
|
||||
```nix
|
||||
pythonImportsCheck = ["mymodule"]; # Check this is correct
|
||||
# Or if importing creates side effects:
|
||||
pythonImportsCheck = [];
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
See existing packages in the repository:
|
||||
|
||||
- `pkgs/code2prompt/` - Rust package
|
||||
- `pkgs/mem0/` - Python package
|
||||
- `pkgs/hyprpaper-random/` - Shell script
|
||||
- `pkgs/msty-studio/` - AppImage
|
||||
- `pkgs/zellij-ps/` - Fetch from Gitea
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Architecture](../ARCHITECTURE.md) - Understanding package organization
|
||||
- [Using Modules](./using-modules.md) - If you need to create modules
|
||||
- [Contributing](../CONTRIBUTING.md) - Code style and guidelines
|
||||
527
docs/guides/development-workflow.md
Normal file
527
docs/guides/development-workflow.md
Normal file
@@ -0,0 +1,527 @@
|
||||
# Development Workflow Guide
|
||||
|
||||
Development, testing, and contribution workflow for m3ta-nixpkgs.
|
||||
|
||||
## Initial Setup
|
||||
|
||||
### Clone Repository
|
||||
|
||||
```bash
|
||||
git clone https://code.m3ta.dev/m3tam3re/nixpkgs.git
|
||||
cd nixpkgs
|
||||
```
|
||||
|
||||
### Enter Development Shell
|
||||
|
||||
```bash
|
||||
# Default shell (includes linting tools)
|
||||
nix develop
|
||||
|
||||
# Python shell
|
||||
nix develop .#python
|
||||
|
||||
# DevOps shell
|
||||
nix develop .#devops
|
||||
```
|
||||
|
||||
### Development Shell Tools
|
||||
|
||||
The default dev shell includes:
|
||||
|
||||
- `statix` - Nix linter
|
||||
- `deadnix` - Find dead code
|
||||
- `alejandra` - Code formatter
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Create Feature Branch
|
||||
|
||||
```bash
|
||||
# Checkout main and pull latest
|
||||
git checkout main
|
||||
git pull
|
||||
|
||||
# Create feature branch
|
||||
git checkout -b feature/my-new-package
|
||||
```
|
||||
|
||||
### 2. Make Changes
|
||||
|
||||
```bash
|
||||
# Create new package
|
||||
mkdir -p pkgs/my-package
|
||||
vim pkgs/my-package/default.nix
|
||||
|
||||
# Or modify existing package
|
||||
vim pkgs/existing-package/default.nix
|
||||
|
||||
# Or add module
|
||||
vim modules/nixos/my-module.nix
|
||||
```
|
||||
|
||||
### 3. Format Code
|
||||
|
||||
```bash
|
||||
# Format all files
|
||||
nix fmt
|
||||
|
||||
# Format specific file
|
||||
alejandra path/to/file.nix
|
||||
```
|
||||
|
||||
**Always format before committing.**
|
||||
|
||||
### 4. Test Changes
|
||||
|
||||
#### Build Package
|
||||
|
||||
```bash
|
||||
# Build specific package
|
||||
nix build .#my-package
|
||||
|
||||
# Build all packages
|
||||
nix build .#packages.x86_64-linux
|
||||
```
|
||||
|
||||
#### Run Package
|
||||
|
||||
```bash
|
||||
# Test if package runs
|
||||
nix run .#my-package -- --help
|
||||
|
||||
# Or enter shell with package
|
||||
nix shell .#my-package
|
||||
my-package --version
|
||||
```
|
||||
|
||||
#### Validate Flake
|
||||
|
||||
```bash
|
||||
# Validate all outputs
|
||||
nix flake check
|
||||
|
||||
# Show all outputs
|
||||
nix flake show
|
||||
```
|
||||
|
||||
#### Test Module
|
||||
|
||||
```bash
|
||||
# Test NixOS configuration
|
||||
sudo nixos-rebuild test --flake .#hostname
|
||||
|
||||
# Test Home Manager configuration
|
||||
home-manager switch --flake .#username@hostname
|
||||
```
|
||||
|
||||
### 5. Lint Code
|
||||
|
||||
```bash
|
||||
# Enter dev shell for linting tools
|
||||
nix develop
|
||||
|
||||
# Run statix
|
||||
statix check .
|
||||
|
||||
# Run deadnix
|
||||
deadnix .
|
||||
|
||||
# Fix auto-fixable issues
|
||||
statix fix .
|
||||
```
|
||||
|
||||
### 6. Commit Changes
|
||||
|
||||
```bash
|
||||
# Stage changes
|
||||
git add .
|
||||
|
||||
# Commit with conventional format
|
||||
git commit -m "feat: add my-package for doing X"
|
||||
|
||||
# Commit types: feat, fix, docs, style, refactor, chore, test
|
||||
```
|
||||
|
||||
### 7. Push and Create PR
|
||||
|
||||
```bash
|
||||
# Push branch
|
||||
git push origin feature/my-new-package
|
||||
|
||||
# Create PR via web interface or CLI
|
||||
gh pr create --title "feat: add my-package" --body "Description of changes"
|
||||
```
|
||||
|
||||
## Testing Strategies
|
||||
|
||||
### Local Testing
|
||||
|
||||
#### Test Package Build
|
||||
|
||||
```bash
|
||||
# Build for current system
|
||||
nix build .#my-package
|
||||
|
||||
# Build for specific system
|
||||
nix build .#my-package --system aarch64-linux
|
||||
|
||||
# Build for macOS
|
||||
nix build .#my-package --system x86_64-darwin
|
||||
```
|
||||
|
||||
#### Test Package Functionality
|
||||
|
||||
```bash
|
||||
# Enter shell with package
|
||||
nix shell .#my-package
|
||||
|
||||
# Run the program
|
||||
my-package --help
|
||||
my-package --version
|
||||
|
||||
# Test with sample data
|
||||
echo "test" | my-package
|
||||
```
|
||||
|
||||
#### Test Configuration
|
||||
|
||||
```bash
|
||||
# Test NixOS configuration
|
||||
sudo nixos-rebuild test --flake .#hostname
|
||||
|
||||
# Test Home Manager configuration
|
||||
home-manager switch --flake .#username@hostname
|
||||
|
||||
# Check configuration syntax
|
||||
nix eval .#nixosConfigurations.hostname.config --apply builtins.attrNames
|
||||
```
|
||||
|
||||
### Integration Testing
|
||||
|
||||
#### Test with Real Services
|
||||
|
||||
```bash
|
||||
# If package is a service
|
||||
# 1. Add to configuration
|
||||
# 2. Apply configuration
|
||||
sudo nixos-rebuild switch
|
||||
|
||||
# 3. Test service
|
||||
systemctl status my-service
|
||||
journalctl -u my-service -f
|
||||
|
||||
# 4. Test functionality
|
||||
curl http://localhost:8080
|
||||
```
|
||||
|
||||
#### Test with Dependencies
|
||||
|
||||
```bash
|
||||
# Build dependency chain
|
||||
nix build .#my-package \
|
||||
--rebuild \
|
||||
--keep-going
|
||||
|
||||
# Check if dependencies are satisfied
|
||||
nix path-info .#my-package --references
|
||||
```
|
||||
|
||||
## Continuous Integration
|
||||
|
||||
### Pre-Commit Hook
|
||||
|
||||
Create `.git/hooks/pre-commit`:
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Format code
|
||||
nix fmt
|
||||
|
||||
# Lint
|
||||
statix check .
|
||||
deadnix .
|
||||
|
||||
# Validate
|
||||
nix flake check
|
||||
|
||||
# Test build
|
||||
nix build .#your-package
|
||||
```
|
||||
|
||||
Make executable:
|
||||
|
||||
```bash
|
||||
chmod +x .git/hooks/pre-commit
|
||||
```
|
||||
|
||||
### Pre-Push Hook
|
||||
|
||||
Create `.git/hooks/pre-push`:
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Validate flake
|
||||
nix flake check
|
||||
|
||||
# Run tests if they exist
|
||||
# make test
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
### Build Failures
|
||||
|
||||
#### Hash Mismatch
|
||||
|
||||
Error: `got: sha256-AAAAAAAA... expected: sha256-BBBBBB...`
|
||||
|
||||
Solution: Copy the `got` hash and update package:
|
||||
|
||||
```nix
|
||||
src = fetchFromGitHub {
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Use actual hash
|
||||
};
|
||||
```
|
||||
|
||||
#### Dependency Not Found
|
||||
|
||||
Error: `error: undefined variable 'somelib'`
|
||||
|
||||
Solution: Check function arguments:
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
somelib, # Add this if missing
|
||||
}:
|
||||
```
|
||||
|
||||
#### Build Failed
|
||||
|
||||
Error: `builder for '/nix/store/...' failed`
|
||||
|
||||
Solution:
|
||||
|
||||
```bash
|
||||
# Build with verbose output
|
||||
nix build .#my-package -v --show-trace
|
||||
|
||||
# Check build logs
|
||||
nix log .#my-package
|
||||
|
||||
# Enter build environment for debugging
|
||||
nix shell -f .#my-package .bashInteractive
|
||||
```
|
||||
|
||||
### Runtime Failures
|
||||
|
||||
#### Package Not Executable
|
||||
|
||||
Error: `error: operation not permitted`
|
||||
|
||||
Solution: Check `mainProgram` in meta:
|
||||
|
||||
```nix
|
||||
meta = with lib; {
|
||||
mainProgram = "my-app"; # Must match executable name
|
||||
};
|
||||
```
|
||||
|
||||
#### Library Not Found
|
||||
|
||||
Error: `error while loading shared libraries: libfoo.so`
|
||||
|
||||
Solution: Add to build inputs:
|
||||
|
||||
```nix
|
||||
buildInputs = [someLib];
|
||||
```
|
||||
|
||||
### Configuration Failures
|
||||
|
||||
#### Option Not Found
|
||||
|
||||
Error: `error: The option 'm3ta.mymodule' does not exist`
|
||||
|
||||
Solution: Import the module:
|
||||
|
||||
```nix
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
];
|
||||
```
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Update Package Version
|
||||
|
||||
```bash
|
||||
# 1. Update version in package definition
|
||||
vim pkgs/my-package/default.nix
|
||||
|
||||
# 2. Build to get new hash
|
||||
nix build .#my-package
|
||||
|
||||
# 3. Update hash from error message
|
||||
|
||||
# 4. Test new version
|
||||
nix run .#my-package -- --version
|
||||
|
||||
# 5. Commit
|
||||
git commit -m "chore: update my-package to v2.0.0"
|
||||
```
|
||||
|
||||
### Update Dependencies
|
||||
|
||||
```bash
|
||||
# 1. Update fetcher version/rev
|
||||
vim pkgs/my-package/default.nix
|
||||
|
||||
# 2. Update dependencies if needed
|
||||
vim pkgs/my-package/default.nix
|
||||
|
||||
# 3. Build and test
|
||||
nix build .#my-package
|
||||
nix run .#my-package -- --help
|
||||
|
||||
# 4. Commit
|
||||
git commit -m "fix: update dependencies for my-package"
|
||||
```
|
||||
|
||||
### Add Tests
|
||||
|
||||
```bash
|
||||
# 1. Add test to package
|
||||
vim pkgs/my-package/default.nix
|
||||
|
||||
# 2. Run tests
|
||||
nix build .#my-package
|
||||
|
||||
# 3. Verify tests pass
|
||||
|
||||
# 4. Commit
|
||||
git commit -m "test: add tests for my-package"
|
||||
```
|
||||
|
||||
### Fix Linting Issues
|
||||
|
||||
```bash
|
||||
# 1. Run linter
|
||||
nix develop
|
||||
statix check .
|
||||
|
||||
# 2. Fix issues manually or auto-fix
|
||||
statix fix .
|
||||
|
||||
# 3. Check again
|
||||
statix check .
|
||||
|
||||
# 4. Commit
|
||||
git commit -m "style: fix linting issues"
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Use Caching
|
||||
|
||||
```bash
|
||||
# Use binary cache (if available)
|
||||
nix build .#my-package --substituters https://cache.nixos.org https://your-cache.example.com
|
||||
|
||||
# Use local cache
|
||||
nix build .#my-package --max-jobs 4
|
||||
```
|
||||
|
||||
### Parallel Builds
|
||||
|
||||
```bash
|
||||
# Build multiple packages in parallel
|
||||
nix build .#package1 .#package2 .#package3
|
||||
```
|
||||
|
||||
### Incremental Builds
|
||||
|
||||
```bash
|
||||
# Only rebuild changed packages
|
||||
nix build .#my-package --check
|
||||
|
||||
# Don't rebuild dependencies
|
||||
nix build .#my-package --no-link
|
||||
```
|
||||
|
||||
## Release Process
|
||||
|
||||
### Version Bump
|
||||
|
||||
```bash
|
||||
# 1. Update versions as needed
|
||||
vim pkgs/*/default.nix
|
||||
|
||||
# 2. Update CHANGELOG.md
|
||||
vim CHANGELOG.md
|
||||
|
||||
# 3. Test all packages
|
||||
nix flake check
|
||||
|
||||
# 4. Commit
|
||||
git commit -m "chore: prepare release v1.0.0"
|
||||
```
|
||||
|
||||
### Tag Release
|
||||
|
||||
```bash
|
||||
# Create tag
|
||||
git tag -a v1.0.0 -m "Release v1.0.0"
|
||||
|
||||
# Push tag
|
||||
git push origin v1.0.0
|
||||
|
||||
# Push with tags
|
||||
git push --follow-tags
|
||||
```
|
||||
|
||||
### Update Flakes
|
||||
|
||||
Update flake lock after release:
|
||||
|
||||
```bash
|
||||
# Update lock file
|
||||
nix flake update
|
||||
|
||||
# Commit
|
||||
git commit -m "chore: update flake lock"
|
||||
```
|
||||
|
||||
## Checklist
|
||||
|
||||
### Before Committing
|
||||
|
||||
- [ ] Code formatted with `nix fmt`
|
||||
- [ ] Passes `statix check .`
|
||||
- [ ] Passes `deadnix .`
|
||||
- [ ] Passes `nix flake check`
|
||||
- [ ] Package builds successfully
|
||||
- [ ] Package runs as expected
|
||||
- [ ] Documentation updated (if needed)
|
||||
- [ ] Commit message follows convention
|
||||
|
||||
### Before Merging PR
|
||||
|
||||
- [ ] All tests pass
|
||||
- [ ] Code review approved
|
||||
- [ ] No merge conflicts
|
||||
- [ ] Documentation complete
|
||||
- [ ] Breaking changes documented
|
||||
|
||||
## Resources
|
||||
|
||||
- [Contributing Guide](../CONTRIBUTING.md) - Code style and guidelines
|
||||
- [Architecture](../ARCHITECTURE.md) - Understanding repository structure
|
||||
- [Adding Packages](./adding-packages.md) - Package creation guide
|
||||
- [Quick Start](../QUICKSTART.md) - Getting started guide
|
||||
402
docs/guides/getting-started.md
Normal file
402
docs/guides/getting-started.md
Normal file
@@ -0,0 +1,402 @@
|
||||
# Getting Started Guide
|
||||
|
||||
Initial setup and basic usage of m3ta-nixpkgs.
|
||||
|
||||
## Installation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Make sure you have Nix installed with flakes enabled:
|
||||
|
||||
```bash
|
||||
# Check Nix version (need 2.4+)
|
||||
nix --version
|
||||
|
||||
# Enable flakes (in /etc/nixos/configuration.nix)
|
||||
nix.settings.experimental-features = ["nix-command" "flakes"]
|
||||
|
||||
# Rebuild NixOS
|
||||
sudo nixos-rebuild switch
|
||||
```
|
||||
|
||||
### Adding to Your Flake
|
||||
|
||||
#### Option 1: NixOS Configuration
|
||||
|
||||
Add to your `flake.nix`:
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "My NixOS configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager";
|
||||
|
||||
m3ta-nixpkgs = {
|
||||
url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
home-manager,
|
||||
m3ta-nixpkgs,
|
||||
...
|
||||
}: {
|
||||
nixosConfigurations = {
|
||||
myhost = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
./hardware-configuration.nix
|
||||
|
||||
# Import m3ta-nixpkgs modules
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
|
||||
# Apply overlay
|
||||
({pkgs, ...}: {
|
||||
nixpkgs.overlays = [m3ta-nixpkgs.overlays.default];
|
||||
|
||||
# Packages from m3ta-nixpkgs are now available
|
||||
environment.systemPackages = with pkgs; [
|
||||
code2prompt
|
||||
zellij-ps
|
||||
];
|
||||
})
|
||||
|
||||
# Home Manager integration
|
||||
home-manager.nixosModules.home-manager
|
||||
{
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.myusername = {
|
||||
imports = [m3ta-nixpkgs.homeManagerModules.default];
|
||||
home.packages = with pkgs; [
|
||||
launch-webapp
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### Option 2: Standalone Home Manager
|
||||
|
||||
```nix
|
||||
{
|
||||
description = "My Home Manager configuration";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
home-manager.url = "github:nix-community/home-manager";
|
||||
|
||||
m3ta-nixpkgs = {
|
||||
url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
home-manager,
|
||||
m3ta-nixpkgs,
|
||||
}: let
|
||||
system = "x86_64-linux";
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [m3ta-nixpkgs.overlays.default];
|
||||
};
|
||||
in {
|
||||
homeConfigurations.myusername = home-manager.lib.homeManagerConfiguration {
|
||||
inherit pkgs;
|
||||
modules = [
|
||||
m3ta-nixpkgs.homeManagerModules.default
|
||||
{
|
||||
home.username = "myusername";
|
||||
home.homeDirectory = "/home/myusername";
|
||||
home.packages = with pkgs; [
|
||||
code2prompt
|
||||
zellij-ps
|
||||
];
|
||||
programs.home-manager.enable = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Quick Usage
|
||||
|
||||
### Using Packages Directly
|
||||
|
||||
Without adding to your configuration:
|
||||
|
||||
```bash
|
||||
# Build a package
|
||||
nix build git+https://code.m3ta.dev/m3tam3re/nixpkgs#code2prompt
|
||||
|
||||
# Run a package
|
||||
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#zellij-ps
|
||||
|
||||
# List all available packages
|
||||
nix flake show git+https://code.m3ta.dev/m3tam3re/nixpkgs
|
||||
```
|
||||
|
||||
### Using Packages in Configuration
|
||||
|
||||
After applying overlay:
|
||||
|
||||
```nix
|
||||
# System-wide (NixOS)
|
||||
environment.systemPackages = with pkgs; [
|
||||
code2prompt
|
||||
zellij-ps
|
||||
];
|
||||
|
||||
# User-only (Home Manager)
|
||||
home.packages = with pkgs; [
|
||||
launch-webapp
|
||||
];
|
||||
```
|
||||
|
||||
### Using Modules
|
||||
|
||||
```nix
|
||||
# Import all modules
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
];
|
||||
|
||||
# Or import specific module
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.mem0
|
||||
];
|
||||
|
||||
# Configure module
|
||||
m3ta.mem0 = {
|
||||
enable = true;
|
||||
port = 8000;
|
||||
};
|
||||
```
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Install a Package System-Wide
|
||||
|
||||
```nix
|
||||
# /etc/nixos/configuration.nix
|
||||
{pkgs, ...}: {
|
||||
environment.systemPackages = with pkgs; [
|
||||
code2prompt
|
||||
hyprpaper-random
|
||||
];
|
||||
}
|
||||
|
||||
# Apply
|
||||
sudo nixos-rebuild switch
|
||||
```
|
||||
|
||||
### Install a Package for Your User
|
||||
|
||||
```nix
|
||||
# home.nix
|
||||
{pkgs, ...}: {
|
||||
home.packages = with pkgs; [
|
||||
launch-webapp
|
||||
zellij-ps
|
||||
];
|
||||
}
|
||||
|
||||
# Apply
|
||||
home-manager switch
|
||||
```
|
||||
|
||||
### Enable a NixOS Module
|
||||
|
||||
```nix
|
||||
# /etc/nixos/configuration.nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
];
|
||||
|
||||
m3ta.mem0 = {
|
||||
enable = true;
|
||||
port = 8000;
|
||||
};
|
||||
|
||||
# Apply
|
||||
# sudo nixos-rebuild switch
|
||||
}
|
||||
```
|
||||
|
||||
### Enable a Home Manager Module
|
||||
|
||||
```nix
|
||||
# home.nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.homeManagerModules.default
|
||||
];
|
||||
|
||||
m3ta.cli.zellij-ps = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
# Apply
|
||||
# home-manager switch
|
||||
}
|
||||
```
|
||||
|
||||
### Use Port Management
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
nginx = 80;
|
||||
grafana = 3000;
|
||||
};
|
||||
hostOverrides.laptop = {
|
||||
nginx = 8080;
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
httpConfig = ''
|
||||
server {
|
||||
listen ${toString (config.m3ta.ports.get "nginx")};
|
||||
root /var/www;
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Available Packages
|
||||
|
||||
| Package | Description |
|
||||
| ------------------ | ------------------------------------- |
|
||||
| `code2prompt` | Convert code to prompts |
|
||||
| `hyprpaper-random` | Random wallpaper setter for Hyprpaper |
|
||||
| `launch-webapp` | Launch web applications |
|
||||
| `mem0` | AI memory assistant with vector storage |
|
||||
| `msty-studio` | Msty Studio application |
|
||||
| `pomodoro-timer` | Pomodoro timer utility |
|
||||
| `tuxedo-backlight` | Backlight control for Tuxedo laptops |
|
||||
| `zellij-ps` | Project switcher for Zellij |
|
||||
|
||||
## Available Modules
|
||||
|
||||
### NixOS Modules
|
||||
|
||||
- `ports` - Port management across hosts
|
||||
- `mem0` - Mem0 REST API server
|
||||
|
||||
### Home Manager Modules
|
||||
|
||||
- `ports` - Port management (with `generateEnvVars`)
|
||||
- `cli.zellij-ps` - Zellij project switcher
|
||||
- `coding.editors` - Editor configurations
|
||||
|
||||
## Development
|
||||
|
||||
### Development Shells
|
||||
|
||||
```bash
|
||||
# Default dev shell
|
||||
nix develop
|
||||
|
||||
# Python dev shell
|
||||
nix develop .#python
|
||||
|
||||
# DevOps dev shell
|
||||
nix develop .#devops
|
||||
```
|
||||
|
||||
### Building and Testing
|
||||
|
||||
```bash
|
||||
# Build package
|
||||
nix build .#code2prompt
|
||||
|
||||
# Validate flake
|
||||
nix flake check
|
||||
|
||||
# List outputs
|
||||
nix flake show
|
||||
|
||||
# Format code
|
||||
nix fmt
|
||||
```
|
||||
|
||||
### Linting (in dev shell)
|
||||
|
||||
```bash
|
||||
nix develop
|
||||
|
||||
# Run linter
|
||||
statix check .
|
||||
|
||||
# Find dead code
|
||||
deadnix .
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Package Not Found
|
||||
|
||||
**Error**: `error: undefined variable 'code2prompt'`
|
||||
|
||||
**Solution**: Make sure you applied the overlay:
|
||||
|
||||
```nix
|
||||
nixpkgs.overlays = [m3ta-nixpkgs.overlays.default];
|
||||
```
|
||||
|
||||
### Module Not Found
|
||||
|
||||
**Error**: `error: The option 'm3ta.mem0' does not exist`
|
||||
|
||||
**Solution**: Make sure you imported the module:
|
||||
|
||||
```nix
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
# or
|
||||
m3ta-nixpkgs.nixosModules.mem0
|
||||
];
|
||||
```
|
||||
|
||||
### Hash Mismatch
|
||||
|
||||
**Error**: `got: sha256-AAAAAAAA... expected: sha256-BBBBBB...`
|
||||
|
||||
**Solution**: Copy the `got` hash from the error and update the package definition.
|
||||
|
||||
### Building for Different System
|
||||
|
||||
```bash
|
||||
# Build for aarch64-linux
|
||||
nix build .#code2prompt --system aarch64-linux
|
||||
|
||||
# Build for macOS
|
||||
nix build .#code2prompt --system x86_64-darwin
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Adding Packages](./adding-packages.md) - How to add new packages
|
||||
- [Using Modules](./using-modules.md) - Deep dive into modules
|
||||
- [Port Management](./port-management.md) - Managing service ports
|
||||
- [Architecture](../ARCHITECTURE.md) - Understanding the repository structure
|
||||
525
docs/guides/port-management.md
Normal file
525
docs/guides/port-management.md
Normal file
@@ -0,0 +1,525 @@
|
||||
# Port Management Guide
|
||||
|
||||
Managing service ports across multiple hosts with the `m3ta.ports` module.
|
||||
|
||||
## Overview
|
||||
|
||||
The port management module provides a centralized way to define service ports that can have host-specific overrides. This prevents port conflicts and makes it easy to manage services across multiple machines.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Enable Port Management
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
|
||||
# Define default ports
|
||||
definitions = {
|
||||
nginx = 80;
|
||||
grafana = 3000;
|
||||
prometheus = 9090;
|
||||
homepage = 8080;
|
||||
};
|
||||
|
||||
# Define host-specific overrides
|
||||
hostOverrides = {
|
||||
laptop = {
|
||||
nginx = 8080; # Override on laptop
|
||||
homepage = 3001; # Override on laptop
|
||||
};
|
||||
server = {
|
||||
homepage = 3002; # Override on server
|
||||
};
|
||||
};
|
||||
|
||||
# Set current host (determines which overrides to use)
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Using Ports
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
httpConfig = ''
|
||||
server {
|
||||
listen ${toString (config.m3ta.ports.get "nginx")};
|
||||
root /var/www;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings.server.http_port = config.m3ta.ports.get "grafana";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Module Options
|
||||
|
||||
### `m3ta.ports.enable`
|
||||
|
||||
Enable port management module.
|
||||
|
||||
- Type: `boolean`
|
||||
- Default: `false`
|
||||
|
||||
### `m3ta.ports.definitions`
|
||||
|
||||
Default port definitions.
|
||||
|
||||
- Type: `attrsOf int`
|
||||
- Default: `{}`
|
||||
|
||||
```nix
|
||||
definitions = {
|
||||
nginx = 80;
|
||||
grafana = 3000;
|
||||
prometheus = 9090;
|
||||
};
|
||||
```
|
||||
|
||||
### `m3ta.ports.hostOverrides`
|
||||
|
||||
Host-specific port overrides.
|
||||
|
||||
- Type: `attrsOf (attrsOf int)`
|
||||
- Default: `{}`
|
||||
|
||||
```nix
|
||||
hostOverrides = {
|
||||
laptop = {
|
||||
nginx = 8080;
|
||||
grafana = 3001;
|
||||
};
|
||||
server = {
|
||||
grafana = 3002;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### `m3ta.ports.currentHost`
|
||||
|
||||
Current hostname. Determines which overrides to apply.
|
||||
|
||||
- Type: `string`
|
||||
- Example: `config.networking.hostName`
|
||||
|
||||
```nix
|
||||
currentHost = "laptop"; # Use laptop overrides
|
||||
```
|
||||
|
||||
### `m3ta.ports.generateEnvVars` (Home Manager only)
|
||||
|
||||
Generate environment variables from ports.
|
||||
|
||||
- Type: `boolean`
|
||||
- Default: `false` (Home Manager)
|
||||
- NixOS: Not available
|
||||
|
||||
When enabled, generates environment variables like:
|
||||
- `PORT_NGINX=8080`
|
||||
- `PORT_GRAFANA=3000`
|
||||
|
||||
## Functions
|
||||
|
||||
### `config.m3ta.ports.get "service"`
|
||||
|
||||
Get port for a service with host-specific override.
|
||||
|
||||
```nix
|
||||
services.nginx = {
|
||||
port = config.m3ta.ports.get "nginx";
|
||||
};
|
||||
```
|
||||
|
||||
If current host is `laptop` and `hostOverrides.laptop.nginx = 8080`, returns `8080`.
|
||||
If no override, returns default `80`.
|
||||
|
||||
### `config.m3ta.ports.getHostPorts "hostname"`
|
||||
|
||||
Get all ports for a specific host.
|
||||
|
||||
```nix
|
||||
# Get all ports for laptop
|
||||
laptopPorts = config.m3ta.ports.getHostPorts "laptop";
|
||||
# Returns: { nginx = 8080; grafana = 3000; ... }
|
||||
```
|
||||
|
||||
### `config.m3ta.ports.listServices`
|
||||
|
||||
List all defined service names.
|
||||
|
||||
```nix
|
||||
allServices = config.m3ta.ports.listServices;
|
||||
# Returns: ["nginx" "grafana" "prometheus" "homepage"]
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### NixOS Configuration
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
# Define ports
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
nginx = 80;
|
||||
grafana = 3000;
|
||||
prometheus = 9090;
|
||||
loki = 3100;
|
||||
promtail = 9080;
|
||||
};
|
||||
hostOverrides.laptop = {
|
||||
nginx = 8080;
|
||||
grafana = 3001;
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
# Use ports
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
httpConfig = ''
|
||||
server {
|
||||
listen ${toString (config.m3ta.ports.get "nginx")};
|
||||
root /var/www;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings.server.http_port = config.m3ta.ports.get "grafana";
|
||||
};
|
||||
|
||||
services.prometheus = {
|
||||
enable = true;
|
||||
port = config.m3ta.ports.get "prometheus";
|
||||
};
|
||||
|
||||
services.loki = {
|
||||
enable = true;
|
||||
configuration.http_listen_port = config.m3ta.ports.get "loki";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Home Manager Configuration
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
# Define ports
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
dev-server = 3000;
|
||||
nextjs = 3001;
|
||||
vite = 5173;
|
||||
};
|
||||
hostOverrides.desktop = {
|
||||
vite = 5174;
|
||||
};
|
||||
currentHost = "desktop";
|
||||
generateEnvVars = true; # Generate env vars
|
||||
};
|
||||
|
||||
# Ports are now available as env vars
|
||||
# PORT_DEV_SERVER=3000
|
||||
# PORT_NEXTJS=3001
|
||||
# PORT_VITE=5174
|
||||
|
||||
home.sessionVariables = {
|
||||
DEV_PORT = toString (config.m3ta.ports.get "dev-server");
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### With Custom Modules
|
||||
|
||||
Using ports with custom modules (e.g., `m3ta.mem0`):
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
# Define ports
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
mem0 = 8000;
|
||||
qdrant = 6333;
|
||||
};
|
||||
hostOverrides.laptop = {
|
||||
mem0 = 8080;
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
# Use with mem0 module
|
||||
m3ta.mem0 = {
|
||||
enable = true;
|
||||
port = config.m3ta.ports.get "mem0"; # 8000 or 8080 on laptop
|
||||
};
|
||||
|
||||
# Use with qdrant service
|
||||
services.qdrant = {
|
||||
enable = true;
|
||||
port = config.m3ta.ports.get "qdrant";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Port File Generation
|
||||
|
||||
Generate a JSON file with all ports:
|
||||
|
||||
```nix
|
||||
{config, pkgs, ...}: {
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
service1 = 80;
|
||||
service2 = 443;
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
# Generate port file
|
||||
environment.etc."m3ta/ports.json".text = builtins.toJSON (
|
||||
config.m3ta.ports.getHostPorts config.networking.hostName
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Conditional Configuration
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
# Only open firewall if binding to non-localhost
|
||||
httpConfig = let
|
||||
port = config.m3ta.ports.get "nginx";
|
||||
in ''
|
||||
server {
|
||||
listen ${toString port};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts =
|
||||
if config.m3ta.ports.get "nginx" == 80
|
||||
then [80]
|
||||
else [];
|
||||
}
|
||||
```
|
||||
|
||||
### Port Ranges
|
||||
|
||||
```nix
|
||||
definitions = {
|
||||
service-start = 8000;
|
||||
service-end = 8999;
|
||||
};
|
||||
|
||||
# Use in config
|
||||
services.my-app = {
|
||||
portRange = [
|
||||
config.m3ta.ports.get "service-start"
|
||||
config.m3ta.ports.get "service-end"
|
||||
];
|
||||
};
|
||||
```
|
||||
|
||||
### Dynamic Port Allocation
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
# Reserve port ranges
|
||||
app-range-start = 9000;
|
||||
app-range-end = 9999;
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
# Calculate next available port
|
||||
services.my-app = {
|
||||
port = config.m3ta.ports.get "app-range-start" + 0;
|
||||
};
|
||||
|
||||
services.my-other-app = {
|
||||
port = config.m3ta.ports.get "app-range-start" + 1;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Use Descriptive Service Names
|
||||
|
||||
```nix
|
||||
# Good
|
||||
definitions = {
|
||||
nginx = 80;
|
||||
grafana = 3000;
|
||||
prometheus-ui = 9090;
|
||||
prometheus-push = 9091;
|
||||
};
|
||||
|
||||
# Avoid
|
||||
definitions = {
|
||||
p1 = 80;
|
||||
p2 = 3000;
|
||||
p3 = 9090;
|
||||
};
|
||||
```
|
||||
|
||||
### Group Related Services
|
||||
|
||||
```nix
|
||||
definitions = {
|
||||
# Monitoring stack
|
||||
grafana = 3000;
|
||||
prometheus = 9090;
|
||||
loki = 3100;
|
||||
promtail = 9080;
|
||||
|
||||
# Web services
|
||||
nginx = 80;
|
||||
homepage = 8080;
|
||||
|
||||
# Databases
|
||||
postgres = 5432;
|
||||
redis = 6379;
|
||||
qdrant = 6333;
|
||||
};
|
||||
```
|
||||
|
||||
### Document Overrides
|
||||
|
||||
```nix
|
||||
hostOverrides = {
|
||||
# Laptop: Running multiple dev servers, use higher ports
|
||||
laptop = {
|
||||
nginx = 8080;
|
||||
dev-server = 3000;
|
||||
};
|
||||
|
||||
# Server: Production, use standard ports
|
||||
server = {
|
||||
nginx = 80;
|
||||
dev-server = null; # Disable on server
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### Handle Missing Ports
|
||||
|
||||
```nix
|
||||
services.some-service = {
|
||||
enable = true;
|
||||
port = config.m3ta.ports.get "some-service" or 8080;
|
||||
};
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Service Not Found
|
||||
|
||||
Error: `Service "foo" not defined`
|
||||
|
||||
Solution: Add service to `definitions`:
|
||||
|
||||
```nix
|
||||
definitions = {
|
||||
foo = 8080;
|
||||
};
|
||||
```
|
||||
|
||||
### Current Host Not Set
|
||||
|
||||
Error: `currentHost not set`
|
||||
|
||||
Solution: Set `currentHost`:
|
||||
|
||||
```nix
|
||||
currentHost = config.networking.hostName;
|
||||
```
|
||||
|
||||
### Port Conflict
|
||||
|
||||
Issue: Two services trying to use same port.
|
||||
|
||||
Solution: Define both in port management:
|
||||
|
||||
```nix
|
||||
definitions = {
|
||||
service1 = 8080;
|
||||
service2 = 8081; # Different port
|
||||
};
|
||||
```
|
||||
|
||||
## Migration from Hardcoded Ports
|
||||
|
||||
### Before
|
||||
|
||||
```nix
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
httpConfig = ''
|
||||
server {
|
||||
listen 80;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings.server.http_port = 3000;
|
||||
};
|
||||
```
|
||||
|
||||
### After
|
||||
|
||||
```nix
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
nginx = 80;
|
||||
grafana = 3000;
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
httpConfig = ''
|
||||
server {
|
||||
listen ${toString (config.m3ta.ports.get "nginx")};
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings.server.http_port = config.m3ta.ports.get "grafana";
|
||||
};
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Architecture](../ARCHITECTURE.md) - Understanding the library functions
|
||||
- [Using Modules](./using-modules.md) - Using modules with port management
|
||||
- [Contributing](../CONTRIBUTING.md) - Code style and guidelines
|
||||
605
docs/guides/using-modules.md
Normal file
605
docs/guides/using-modules.md
Normal file
@@ -0,0 +1,605 @@
|
||||
# Using Modules Guide
|
||||
|
||||
How to use NixOS and Home Manager modules from m3ta-nixpkgs.
|
||||
|
||||
## Overview
|
||||
|
||||
Modules in m3ta-nixpkgs provide reusable configuration for NixOS (system-level) and Home Manager (user-level) settings. All modules use the `m3ta.*` namespace.
|
||||
|
||||
## Module Organization
|
||||
|
||||
### NixOS Modules
|
||||
|
||||
Located in `modules/nixos/`:
|
||||
|
||||
```
|
||||
modules/nixos/
|
||||
├── default.nix # Aggregates all NixOS modules
|
||||
├── ports.nix # Port management
|
||||
└── mem0.nix # Mem0 REST API server
|
||||
```
|
||||
|
||||
### Home Manager Modules
|
||||
|
||||
Located in `modules/home-manager/` with categories:
|
||||
|
||||
```
|
||||
modules/home-manager/
|
||||
├── default.nix # Aggregates all HM modules
|
||||
├── ports.nix # Port management
|
||||
├── cli/ # CLI tools
|
||||
│ ├── default.nix # Aggregates CLI modules
|
||||
│ └── zellij-ps.nix
|
||||
└── coding/ # Development tools
|
||||
├── default.nix # Aggregates coding modules
|
||||
└── editors.nix
|
||||
```
|
||||
|
||||
## Importing Modules
|
||||
|
||||
### NixOS Modules
|
||||
|
||||
#### Import All Modules
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### Import Specific Module
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.mem0
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### Import from Local Path
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
./modules/nixos/mem0.nix
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Home Manager Modules
|
||||
|
||||
#### Import All Modules
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.homeManagerModules.default
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### Import Specific Module
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.homeManagerModules.ports
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### Import Category
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
# Import all CLI modules
|
||||
m3ta-nixpkgs.homeManagerModules.cli.zellij-ps
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
## Available Modules
|
||||
|
||||
### NixOS Modules
|
||||
|
||||
#### `m3ta.ports`
|
||||
|
||||
Port management across hosts.
|
||||
|
||||
```nix
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
nginx = 80;
|
||||
grafana = 3000;
|
||||
};
|
||||
hostOverrides.laptop = {
|
||||
nginx = 8080;
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
```
|
||||
|
||||
**Documentation**: [Port Management Guide](./port-management.md)
|
||||
|
||||
#### `m3ta.mem0`
|
||||
|
||||
Mem0 REST API server for AI memory.
|
||||
|
||||
```nix
|
||||
m3ta.mem0 = {
|
||||
enable = true;
|
||||
port = 8000;
|
||||
llm = {
|
||||
provider = "openai";
|
||||
apiKeyFile = "/run/secrets/openai-api-key";
|
||||
model = "gpt-4o-mini";
|
||||
};
|
||||
vectorStore = {
|
||||
provider = "qdrant";
|
||||
config = {
|
||||
host = "localhost";
|
||||
port = 6333;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
**Documentation**: [mem0 Module](../modules/nixos/mem0.md)
|
||||
|
||||
### Home Manager Modules
|
||||
|
||||
#### `m3ta.ports`
|
||||
|
||||
Port management (similar to NixOS, with `generateEnvVars`).
|
||||
|
||||
```nix
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
dev-server = 3000;
|
||||
};
|
||||
generateEnvVars = true;
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
```
|
||||
|
||||
**Documentation**: [Port Management Guide](./port-management.md)
|
||||
|
||||
#### `m3ta.cli.zellij-ps`
|
||||
|
||||
Zellij project switcher for quickly navigating between project folders.
|
||||
|
||||
```nix
|
||||
m3ta.cli.zellij-ps = {
|
||||
enable = true;
|
||||
package = pkgs.zellij-ps;
|
||||
};
|
||||
```
|
||||
|
||||
**Documentation**: [zellij-ps Module](../modules/home-manager/cli/zellij-ps.md)
|
||||
|
||||
#### `m3ta.coding.editors`
|
||||
|
||||
Editor configurations.
|
||||
|
||||
```nix
|
||||
m3ta.coding.editors = {
|
||||
enable = true;
|
||||
neovim.enable = true;
|
||||
zed.enable = true;
|
||||
};
|
||||
```
|
||||
|
||||
**Documentation**: [Editors Module](../modules/home-manager/coding/editors.md)
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Module Configuration
|
||||
|
||||
All modules follow this pattern:
|
||||
|
||||
```nix
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib; let
|
||||
cfg = config.m3ta.myModule;
|
||||
in {
|
||||
options.m3ta.myModule = {
|
||||
enable = mkEnableOption "description";
|
||||
# ... other options
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# ... configuration
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Conditional Configuration
|
||||
|
||||
Use `mkIf` to conditionally apply config:
|
||||
|
||||
```nix
|
||||
config = mkIf cfg.enable {
|
||||
# Only applied when cfg.enable = true
|
||||
services.my-service = {
|
||||
enable = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Multiple Conditions
|
||||
|
||||
Use `mkMerge` for multiple conditions:
|
||||
|
||||
```nix
|
||||
config = mkMerge [
|
||||
(mkIf cfg.feature1.enable {
|
||||
# Applied when feature1 is enabled
|
||||
})
|
||||
(mkIf cfg.feature2.enable {
|
||||
# Applied when feature2 is enabled
|
||||
})
|
||||
];
|
||||
```
|
||||
|
||||
### Optional Dependencies
|
||||
|
||||
```nix
|
||||
options.m3ta.myModule = {
|
||||
enable = mkEnableOption "my module";
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.defaultPackage;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.my-service = {
|
||||
package = cfg.package;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
### Minimal NixOS Configuration
|
||||
|
||||
```nix
|
||||
{pkgs, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
];
|
||||
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
my-service = 8080;
|
||||
};
|
||||
currentHost = "laptop";
|
||||
};
|
||||
|
||||
services.my-custom-service = {
|
||||
enable = true;
|
||||
port = config.m3ta.ports.get "my-service";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Full NixOS Configuration
|
||||
|
||||
```nix
|
||||
{config, pkgs, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
];
|
||||
|
||||
# Port management
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
nginx = 80;
|
||||
grafana = 3000;
|
||||
prometheus = 9090;
|
||||
mem0 = 8000;
|
||||
};
|
||||
hostOverrides.laptop = {
|
||||
nginx = 8080;
|
||||
mem0 = 8081;
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
# Mem0 service
|
||||
m3ta.mem0 = {
|
||||
enable = true;
|
||||
port = config.m3ta.ports.get "mem0";
|
||||
llm = {
|
||||
provider = "openai";
|
||||
apiKeyFile = "/run/secrets/openai-api-key";
|
||||
};
|
||||
vectorStore = {
|
||||
provider = "qdrant";
|
||||
config = {
|
||||
host = "localhost";
|
||||
port = 6333;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Nginx
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
httpConfig = ''
|
||||
server {
|
||||
listen ${toString (config.m3ta.ports.get "nginx")};
|
||||
root /var/www;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# Grafana
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
settings.server.http_port = config.m3ta.ports.get "grafana";
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Minimal Home Manager Configuration
|
||||
|
||||
```nix
|
||||
{pkgs, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.homeManagerModules.default
|
||||
];
|
||||
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
dev-server = 3000;
|
||||
};
|
||||
currentHost = "desktop";
|
||||
};
|
||||
|
||||
home.sessionVariables = {
|
||||
DEV_PORT = toString (config.m3ta.ports.get "dev-server");
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Full Home Manager Configuration
|
||||
|
||||
```nix
|
||||
{config, pkgs, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.homeManagerModules.default
|
||||
];
|
||||
|
||||
# Port management
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
dev-server = 3000;
|
||||
nextjs = 3001;
|
||||
vite = 5173;
|
||||
};
|
||||
hostOverrides.laptop = {
|
||||
vite = 5174;
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
# CLI tools
|
||||
m3ta.cli.zellij-ps = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
# Coding tools
|
||||
m3ta.coding.editors = {
|
||||
enable = true;
|
||||
neovim.enable = true;
|
||||
};
|
||||
|
||||
# Packages
|
||||
home.packages = with pkgs; [
|
||||
code2prompt
|
||||
zellij-ps
|
||||
];
|
||||
|
||||
# Environment variables
|
||||
home.sessionVariables = {
|
||||
EDITOR = "nvim";
|
||||
DEV_SERVER_PORT = toString (config.m3ta.ports.get "dev-server");
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Module Options Reference
|
||||
|
||||
### Standard Options
|
||||
|
||||
All modules typically include:
|
||||
|
||||
| Option | Type | Description |
|
||||
|---------|-------|-------------|
|
||||
| `enable` | `boolean` | Enable the module |
|
||||
| `package` | `package` | Custom package to use |
|
||||
| `extraConfig` | `attrs` | Additional configuration |
|
||||
|
||||
### Port Management Options
|
||||
|
||||
| Option | Type | Description |
|
||||
|---------|-------|-------------|
|
||||
| `definitions` | `attrsOf int` | Default port definitions |
|
||||
| `hostOverrides` | `attrsOf attrs` | Host-specific overrides |
|
||||
| `currentHost` | `string` | Current hostname |
|
||||
| `generateEnvVars` | `boolean` | Generate environment variables (HM only) |
|
||||
|
||||
## Combining with Other Flakes
|
||||
|
||||
### Using Multiple Module Sources
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
# m3ta-nixpkgs modules
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
|
||||
# Other flake modules
|
||||
inputs.impermanence.nixosModules.impermanence
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
];
|
||||
|
||||
# Configure all modules
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {nginx = 80;};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
environment.persistence = {
|
||||
"/persist" = {
|
||||
directories = ["/var/lib/mem0"];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Using with Secrets
|
||||
|
||||
```nix
|
||||
{config, ...}: {
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
inputs.sops-nix.nixosModules.sops
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
openai-api-key = {};
|
||||
};
|
||||
|
||||
m3ta.mem0 = {
|
||||
enable = true;
|
||||
llm = {
|
||||
apiKeyFile = config.sops.secrets.openai-api-key.path;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Module Not Found
|
||||
|
||||
Error: `error: The option 'm3ta.mymodule' does not exist`
|
||||
|
||||
**Solutions**:
|
||||
1. Make sure you imported the module:
|
||||
|
||||
```nix
|
||||
imports = [
|
||||
m3ta-nixpkgs.nixosModules.default
|
||||
];
|
||||
```
|
||||
|
||||
2. Check module name is correct
|
||||
|
||||
```nix
|
||||
# Correct
|
||||
m3ta.mem0.enable = true;
|
||||
|
||||
# Wrong
|
||||
m3ta.mymodule.enable = true; # Doesn't exist
|
||||
```
|
||||
|
||||
### Option Type Mismatch
|
||||
|
||||
Error: `type mismatch at 'm3ta.mymodule.enable', expected a boolean but got a list`
|
||||
|
||||
**Solution**: Check option types in documentation
|
||||
|
||||
```nix
|
||||
# Correct
|
||||
m3ta.mymodule.enable = true;
|
||||
|
||||
# Wrong
|
||||
m3ta.mymodule.enable = [true]; # Should be boolean
|
||||
```
|
||||
|
||||
### Port Not Defined
|
||||
|
||||
Error: `Service "foo" not defined`
|
||||
|
||||
**Solution**: Add to port definitions
|
||||
|
||||
```nix
|
||||
m3ta.ports = {
|
||||
definitions = {
|
||||
foo = 8080; # Add this
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Use Namespaces
|
||||
|
||||
Always use the `m3ta.*` namespace:
|
||||
|
||||
```nix
|
||||
# Good
|
||||
m3ta.mem0.enable = true;
|
||||
|
||||
# Bad (potential conflicts)
|
||||
mem0.enable = true;
|
||||
```
|
||||
|
||||
### Document Your Configuration
|
||||
|
||||
Add comments explaining module usage:
|
||||
|
||||
```nix
|
||||
# Port management for multi-host setup
|
||||
m3ta.ports = {
|
||||
enable = true;
|
||||
definitions = {
|
||||
nginx = 80;
|
||||
grafana = 3000;
|
||||
};
|
||||
hostOverrides.laptop = {
|
||||
nginx = 8080; # Use different port on laptop
|
||||
};
|
||||
currentHost = config.networking.hostName;
|
||||
};
|
||||
|
||||
# Mem0 AI memory service
|
||||
m3ta.mem0 = {
|
||||
enable = true;
|
||||
port = config.m3ta.ports.get "mem0";
|
||||
};
|
||||
```
|
||||
|
||||
### Test Configuration
|
||||
|
||||
```bash
|
||||
# Test NixOS configuration without applying
|
||||
sudo nixos-rebuild test --flake .#hostname
|
||||
|
||||
# Check configuration
|
||||
nix flake check
|
||||
|
||||
# Show all options
|
||||
nix eval .#nixosConfigurations.hostname.config.m3ta --apply builtins.attrNames
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Port Management](./port-management.md) - Detailed port management guide
|
||||
- [Adding Packages](./adding-packages.md) - How to add new packages
|
||||
- [Architecture](../ARCHITECTURE.md) - Understanding module structure
|
||||
- [Contributing](../CONTRIBUTING.md) - Code style and guidelines
|
||||
Reference in New Issue
Block a user