diff --git a/QUICKSTART.md b/QUICKSTART.md index f4c01c2..94b6b38 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -1,45 +1,10 @@ -# Quick Start Guide +# Quick Start Guide - Port Management Module -Get started with m3ta-nixpkgs in 5 minutes! This guide covers the most common use cases. +Get started with centralized port management in 5 minutes! -## Prerequisites +## Installation -Ensure Nix flakes are enabled: - -```bash -# Add to ~/.config/nix/nix.conf or /etc/nix/nix.conf -mkdir -p ~/.config/nix -echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf -``` - -## Quick Usage - -### 1. Try a Package Without Installing - -```bash -# Run a package directly -nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#code2prompt - -# Try it in a temporary shell -nix shell git+https://code.m3ta.dev/m3tam3re/nixpkgs#zellij-ps -``` - -### 2. Install to Your Profile - -```bash -# Install a package -nix profile install git+https://code.m3ta.dev/m3tam3re/nixpkgs#msty-studio - -# List installed packages -nix profile list - -# Remove a package -nix profile remove -``` - -### 3. Add to Your NixOS Configuration - -Edit your `flake.nix`: +### Step 1: Add to your flake inputs ```nix { @@ -47,244 +12,216 @@ Edit your `flake.nix`: nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; m3ta-nixpkgs.url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs"; }; +} +``` - outputs = {nixpkgs, m3ta-nixpkgs, ...}: { - nixosConfigurations.yourhostname = nixpkgs.lib.nixosSystem { - modules = [ - { - nixpkgs.overlays = [m3ta-nixpkgs.overlays.default]; +### Step 2: Choose your configuration type - environment.systemPackages = with pkgs; [ - code2prompt - hyprpaper-random - zellij-ps - ]; - } - ]; +## For NixOS Systems + +### Basic Setup + +```nix +{ + imports = [ inputs.m3ta-nixpkgs.nixosModules.default ]; + + m3ta.ports = { + enable = true; + + definitions = { + nginx = 80; + ssh = 22; + grafana = 3000; + }; + + hostOverrides = { + laptop = { nginx = 8080; ssh = 2222; }; + server = {}; # Uses defaults }; }; } ``` -Then rebuild: +### Using Ports -```bash -sudo nixos-rebuild switch --flake .#yourhostname +```nix +# In any NixOS service configuration: +services.nginx.defaultHTTPListenPort = config.m3ta.ports.get "nginx"; +services.openssh.ports = [ (config.m3ta.ports.get "ssh") ]; + +# Firewall rules: +networking.firewall.allowedTCPPorts = [ + (config.m3ta.ports.get "ssh") + (config.m3ta.ports.get "nginx") +]; ``` -### 4. Add to Home Manager (Standalone) +## For Home Manager -Edit your Home Manager `flake.nix`: +### Basic Setup ```nix { - 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"; - }; + imports = [ inputs.m3ta-nixpkgs.homeManagerModules.default ]; - outputs = {nixpkgs, home-manager, m3ta-nixpkgs, ...}: { - homeConfigurations.m3tam3re = home-manager.lib.homeManagerConfiguration { - pkgs = import nixpkgs { - system = "x86_64-linux"; - overlays = [m3ta-nixpkgs.overlays.default]; - }; + m3ta.ports = { + enable = true; - modules = [ - { - home.packages = with pkgs; [ - code2prompt - pomodoro-timer - ]; - } - ]; + definitions = { + vite-dev = 5173; + jupyter = 8888; + local-api = 8000; }; - }; -} -``` -Then activate: - -```bash -home-manager switch --flake .#m3tam3re -``` - -### 5. Use During Development (Local Path) - -When working on your system configuration: - -```nix -{ - inputs = { - # Use local path during development - m3ta-nixpkgs.url = "path:/home/you/projects/m3ta-nixpkgs"; - # Or use git+file for uncommitted changes - # m3ta-nixpkgs.url = "git+file:///home/you/projects/m3ta-nixpkgs"; - }; -} -``` - -### 6. Use Library Functions - -The repository includes helper functions for common configuration tasks. - -#### Port Management Example - -```nix -{ - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - m3ta-nixpkgs.url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs"; - }; - - outputs = {nixpkgs, m3ta-nixpkgs, ...}: { - nixosConfigurations.laptop = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - specialArgs = {inherit inputs; system = "x86_64-linux";}; - modules = [ - ({inputs, system, config, ...}: let - # Import the library - m3taLib = inputs.m3ta-nixpkgs.lib.${system}; - - # Define all your ports centrally - myPorts = { - ports = { - nginx = 80; - grafana = 3000; - prometheus = 9090; - }; - hostPorts = { - laptop = {nginx = 8080;}; # Override on laptop - }; - }; - - # Create port helpers - ports = m3taLib.ports.mkPortHelpers myPorts; - hostname = config.networking.hostName; - in { - # Use in configuration - services.nginx.defaultHTTPListenPort = ports.getPort "nginx" hostname; - services.grafana.settings.server.http_port = ports.getPort "grafana" hostname; - }) - ]; + hostOverrides = { + laptop = { vite-dev = 5174; }; + desktop = { jupyter = 9999; }; }; + + currentHost = "laptop"; # Set your hostname + generateEnvVars = true; # Creates PORT_* environment variables }; } ``` -See `examples/ports-example.nix` for more examples and `lib/README.md` for full documentation. +### Using Ports -## Available Packages +```nix +# Shell aliases: +programs.bash.shellAliases = { + dev = "PORT=${toString (config.m3ta.ports.get "vite-dev")} npm run dev"; +}; -| Package | Description | Command | -| ------------------ | ------------------------------- | ---------------------------- | -| `code2prompt` | Convert code to LLM prompts | `nix run .#code2prompt` | -| `hyprpaper-random` | Random wallpaper for Hyprpaper | `nix run .#hyprpaper-random` | -| `launch-webapp` | Launch web applications | `nix run .#launch-webapp` | -| `msty-studio` | Msty Studio application | `nix run .#msty-studio` | -| `pomodoro-timer` | Pomodoro timer utility | `nix run .#pomodoro-timer` | -| `tuxedo-backlight` | Tuxedo laptop backlight control | `nix run .#tuxedo-backlight` | -| `zellij-ps` | Process viewer for Zellij | `nix run .#zellij-ps` | +# Environment variables: +home.sessionVariables = { + DEV_URL = "http://localhost:${toString (config.m3ta.ports.get "vite-dev")}"; +}; -## Common Commands - -```bash -# Show all available packages -nix flake show git+https://code.m3ta.dev/m3tam3re/nixpkgs - -# Update the flake lock file -nix flake update - -# Build a specific package -nix build git+https://code.m3ta.dev/m3tam3re/nixpkgs#code2prompt - -# Check flake validity -nix flake check git+https://code.m3ta.dev/m3tam3re/nixpkgs +# Config files: +home.file.".config/myapp/config.json".text = builtins.toJSON { + port = config.m3ta.ports.get "vite-dev"; +}; ``` -## Development Workflow +## Common Patterns -### Adding Your Own Package +### Multi-Host Configuration -1. **Clone the repo:** +```nix +# shared-ports.nix +{ + ports = { + nginx = 80; + ssh = 22; + grafana = 3000; + }; - ```bash - git clone https://code.m3ta.dev/m3tam3re/nixpkgs - cd m3ta-nixpkgs - ``` - -2. **Create package directory:** - - ```bash - mkdir pkgs/my-package - cp templates/package/default.nix pkgs/my-package/ - ``` - -3. **Edit `pkgs/my-package/default.nix`** with your package details - -4. **Register in `pkgs/default.nix`:** - - ```nix - {pkgs, ...}: { - # ... existing packages ... - my-package = pkgs.callPackage ./my-package {}; - } - ``` - -5. **Test it:** - - ```bash - git add -A # Nix flakes require git tracking - nix build .#my-package - ``` - -6. **Commit and push:** - ```bash - git commit -m "feat: add my-package" - git push - ``` - -## Troubleshooting - -### Issue: "experimental-features" error - -**Solution:** Enable flakes in nix.conf (see Prerequisites) - -### Issue: "path is not tracked by Git" - -**Solution:** `git add` your files before running Nix commands - -### Issue: Package fails to build - -**Solution:** - -```bash -# Check build logs -nix build .#package-name --show-trace - -# Try with fresh build -nix build .#package-name --rebuild + hostOverrides = { + laptop = { nginx = 8080; ssh = 2222; }; + server = {}; + }; +} ``` -### Issue: Hash mismatch +```nix +# In your flake.nix +let + sharedPorts = import ./shared-ports.nix; +in { + nixosConfigurations.laptop = nixpkgs.lib.nixosSystem { + modules = [ + m3ta-nixpkgs.nixosModules.default + { + m3ta.ports = { + enable = true; + definitions = sharedPorts.ports; + hostOverrides = sharedPorts.hostOverrides; + currentHost = "laptop"; + }; + } + ]; + }; +} +``` -**Solution:** Use `lib.fakeHash` first, then replace with the correct hash from the error message +### Proxy Configuration + +```nix +services.nginx.virtualHosts."example.com" = { + locations."/grafana/" = { + proxyPass = "http://127.0.0.1:${toString (config.m3ta.ports.get "grafana")}"; + }; + locations."/prometheus/" = { + proxyPass = "http://127.0.0.1:${toString (config.m3ta.ports.get "prometheus")}"; + }; +}; +``` + +### Container Services + +```nix +virtualisation.oci-containers.containers.grafana = { + image = "grafana/grafana:latest"; + ports = [ + "${toString (config.m3ta.ports.get "grafana")}:3000" + ]; +}; +``` + +## Available Functions + +| Function | Description | Example | +| ----------------------------------------------- | -------------------------- | ----------------------------------------------- | +| `config.m3ta.ports.get "service"` | Get port for current host | `config.m3ta.ports.get "nginx"` | +| `config.m3ta.ports.getForHost "host" "service"` | Get port for specific host | `config.m3ta.ports.getForHost "laptop" "nginx"` | +| `config.m3ta.ports.all` | All ports (merged) | `config.m3ta.ports.all` | +| `config.m3ta.ports.services` | List service names | `config.m3ta.ports.services` | + +## Debugging + +### View all configured ports + +```bash +# NixOS +cat /etc/m3ta/ports.json | jq + +# Home Manager +cat ~/.config/m3ta/ports.json | jq +``` + +### Check what port is being used + +```nix +# Add to your config temporarily +environment.etc."debug-ports.txt".text = '' + nginx: ${toString (config.m3ta.ports.get "nginx")} + ssh: ${toString (config.m3ta.ports.get "ssh")} + all: ${builtins.toJSON config.m3ta.ports.all} +''; +``` ## Next Steps -- 📖 Read the full [README.md](README.md) for detailed documentation -- 🤝 Check [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines -- 💡 Browse [examples/](examples/) for more configuration examples -- 🔍 Explore the [templates/](templates/) for creating new packages and modules +- See [examples/ports/README.md](examples/ports/README.md) for comprehensive documentation +- Check [examples/ports/nixos-example.nix](examples/ports/nixos-example.nix) for a full NixOS example +- Check [examples/ports/home-manager-example.nix](examples/ports/home-manager-example.nix) for a full Home Manager example +- Read [examples/ports/flake-example.nix](examples/ports/flake-example.nix) for multi-host setup -## Getting Help +## Common Issues -- 💬 [NixOS Discourse](https://discourse.nixos.org/) -- 💭 [NixOS Matrix Chat](https://matrix.to/#/#nix:nixos.org) -- 📚 [Nix Pills](https://nixos.org/guides/nix-pills/) -- 📖 [Nixpkgs Manual](https://nixos.org/manual/nixpkgs/stable/) +**"Service not defined" error** ---- +- Make sure the service is in your `definitions` block -**Ready to contribute?** See [CONTRIBUTING.md](CONTRIBUTING.md) to get started! +**Wrong port being used** + +- Check your `currentHost` matches your actual hostname +- Verify overrides in `/etc/m3ta/ports.json` or `~/.config/m3ta/ports.json` + +**Type errors** + +- Ports must be integers: `nginx = 80;` not `nginx = "80";` + +## Need Help? + +Open an issue at: https://code.m3ta.dev/m3tam3re/nixpkgs diff --git a/README.md b/README.md index e2d1008..f3b34e1 100644 --- a/README.md +++ b/README.md @@ -32,15 +32,21 @@ m3ta-nixpkgs/ │ └── n8n.nix ├── modules/ │ ├── nixos/ # NixOS modules -│ │ └── default.nix +│ │ ├── default.nix +│ │ └── ports.nix # Port management module │ └── home-manager/ # Home Manager modules │ ├── default.nix +│ ├── ports.nix # Port management module │ └── zellij-ps.nix ├── lib/ # Library functions │ ├── default.nix # Library entry point │ └── ports.nix # Port management utilities ├── examples/ # Usage examples -│ └── ports-example.nix +│ └── ports/ # Port management examples +│ ├── README.md +│ ├── nixos-example.nix +│ ├── home-manager-example.nix +│ └── flake-example.nix └── templates/ # Templates for new packages/modules ``` @@ -126,9 +132,18 @@ Add this repository to your flake inputs: { imports = [ inputs.m3ta-nixpkgs.nixosModules.default + # Or specific modules: + # inputs.m3ta-nixpkgs.nixosModules.ports ]; - # Your custom module options will be available here + # Configure the ports module (if enabled) + m3ta.ports = { + enable = true; + definitions = { + nginx = 80; + ssh = 22; + }; + }; } ``` @@ -239,56 +254,134 @@ homeManagerModules = { }; ``` -### Using Library Functions +## Port Management Module -The repository includes helper functions to simplify common configuration tasks. +**NEW!** Centrally manage service ports across your NixOS systems and Home Manager configurations with automatic host-specific overrides. -#### Port Management +### Features -Centrally manage service ports across multiple hosts with automatic host-specific overrides: +- ✅ **Centralized Configuration**: Define all ports in one place +- ✅ **Host-Specific Overrides**: Different ports for different machines (laptop, server, desktop) +- ✅ **Type Safety**: Full NixOS/Home Manager type system integration +- ✅ **Auto-Generated Files**: JSON exports and environment variables +- ✅ **Easy Integration**: Works with any service configuration +- ✅ **Conflict Prevention**: Avoid port conflicts across different hosts + +### Quick Start - NixOS Module ```nix -# In your flake.nix or configuration { - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - m3ta-nixpkgs.url = "git+https://code.m3ta.dev/m3tam3re/nixpkgs"; + imports = [ inputs.m3ta-nixpkgs.nixosModules.default ]; + + m3ta.ports = { + enable = true; + + definitions = { + nginx = 80; + grafana = 3000; + ssh = 22; + prometheus = 9090; + }; + + hostOverrides = { + laptop = { + nginx = 8080; # Use non-privileged port + ssh = 2222; + }; + }; + + # Automatically uses system hostname + currentHost = config.networking.hostName; }; - outputs = { self, nixpkgs, m3ta-nixpkgs, ... }: { + # Use ports in your configuration + services.nginx.defaultHTTPListenPort = config.m3ta.ports.get "nginx"; + services.openssh.ports = [ (config.m3ta.ports.get "ssh") ]; + + # Firewall with dynamic ports + networking.firewall.allowedTCPPorts = [ + (config.m3ta.ports.get "ssh") + (config.m3ta.ports.get "nginx") + ]; +} +``` + +### Quick Start - Home Manager Module + +```nix +{ + imports = [ inputs.m3ta-nixpkgs.homeManagerModules.default ]; + + m3ta.ports = { + enable = true; + + definitions = { + vite-dev = 5173; + jupyter = 8888; + local-api = 8000; + }; + + hostOverrides = { + laptop = { + vite-dev = 5174; + jupyter = 9999; + }; + }; + + currentHost = "laptop"; + + # Auto-generate PORT_* environment variables + generateEnvVars = true; + }; + + # Use ports in your configuration + programs.bash.shellAliases = { + dev = "PORT=${toString (config.m3ta.ports.get "vite-dev")} npm run dev"; + jupyter = "jupyter lab --port=${toString (config.m3ta.ports.get "jupyter")}"; + }; + + home.sessionVariables = { + DEV_SERVER = "http://localhost:${toString (config.m3ta.ports.get "vite-dev")}"; + }; +} +``` + +### Available Module Functions + +- `config.m3ta.ports.get "service"` - Get port for service on current host +- `config.m3ta.ports.getForHost "host" "service"` - Get port for specific host +- `config.m3ta.ports.all` - All ports for current host (merged defaults + overrides) +- `config.m3ta.ports.allForHost "host"` - All ports for specific host +- `config.m3ta.ports.services` - List all defined service names + +### Auto-Generated Files + +**NixOS**: `/etc/m3ta/ports.json` +**Home Manager**: `~/.config/m3ta/ports.json` + +These files contain all port configuration for easy inspection and external tool integration. + +### Using the Library Directly + +For advanced use cases, you can use the underlying library functions without the module: + +```nix +{ + outputs = { nixpkgs, m3ta-nixpkgs, ... }: { nixosConfigurations.laptop = nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - specialArgs = { inherit inputs; system = "x86_64-linux"; }; modules = [ ({ inputs, system, config, ... }: let - # Import the library m3taLib = inputs.m3ta-nixpkgs.lib.${system}; - # Define all ports in one place myPorts = { - ports = { - nginx = 80; - grafana = 3000; - prometheus = 9090; - }; - hostPorts = { - laptop = { - nginx = 8080; # Non-privileged port on laptop - }; - }; + ports = { nginx = 80; grafana = 3000; }; + hostPorts = { laptop = { nginx = 8080; }; }; }; - # Create helper functions - ports = m3taLib.ports.mkPortHelpers myPorts; + portHelpers = m3taLib.ports.mkPortHelpers myPorts; hostname = config.networking.hostName; in { - # Use in your configuration - services.nginx.defaultHTTPListenPort = ports.getPort "nginx" hostname; - services.grafana.settings.server.http_port = ports.getPort "grafana" hostname; - - # Get all ports for current host - environment.etc."service-ports.json".text = - builtins.toJSON (ports.getHostPorts hostname); + services.nginx.port = portHelpers.getPort "nginx" hostname; }) ]; }; @@ -296,22 +389,15 @@ Centrally manage service ports across multiple hosts with automatic host-specifi } ``` -**Benefits:** +### Documentation -- Single source of truth for all port assignments -- Automatic host-specific overrides (laptop, server, VM, etc.) -- Works across both NixOS and Home Manager configurations -- Easy to see and manage all ports in one place +See comprehensive examples and documentation: -**Available Functions:** - -- `mkPortHelpers`: Create port helper functions from a configuration -- `getPort`: Get port for a service with optional host override -- `getHostPorts`: Get all ports for a specific host (merged defaults + overrides) -- `getDefaultPort`: Get default port without host override -- `listServices`: List all defined service names - -See `examples/ports-example.nix` for comprehensive usage examples. +- `examples/ports/README.md` - Complete guide with all features +- `examples/ports/nixos-example.nix` - Full NixOS configuration example +- `examples/ports/home-manager-example.nix` - Full Home Manager configuration example +- `examples/ports/flake-example.nix` - Complete multi-host flake setup +- `lib/ports.nix` - Library source code with inline documentation ## Available Packages diff --git a/flake.nix b/flake.nix index 581e83d..5be8241 100644 --- a/flake.nix +++ b/flake.nix @@ -56,15 +56,15 @@ # NixOS modules - for system-level configuration nixosModules = { default = ./modules/nixos; - # Add individual modules here as needed - # example: myModule = ./modules/nixos/my-module.nix; + # Individual modules for selective imports + ports = ./modules/nixos/ports.nix; }; # Home Manager modules - for user-level configuration homeManagerModules = { default = import ./modules/home-manager; + ports = import ./modules/home-manager/ports.nix; zellij-ps = import ./modules/home-manager/zellij-ps.nix; - # Add more individual modules as you create them }; # Library functions - helper utilities for your configuration diff --git a/modules/home-manager/default.nix b/modules/home-manager/default.nix index a058a61..16dd1c9 100644 --- a/modules/home-manager/default.nix +++ b/modules/home-manager/default.nix @@ -3,5 +3,6 @@ imports = [ ./cli ./coding + ./ports.nix ]; } diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 717b95f..6f78dce 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -11,6 +11,7 @@ # Add your custom modules here as imports or inline definitions imports = [ + ./ports.nix # Example: ./my-service.nix # Add more module files here as you create them ];