# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a NixOS VPS configuration using flakes. It deploys a private server with: - **SearXNG**: Private meta-search engine with Anubis AI firewall protection - **OpenClaw**: AI agent with Discord integration (uses ZAI/GLM models) - **Nginx**: Reverse proxy with automatic Let's Encrypt certificates ## Commands ### Deploy Configuration ```bash # Apply configuration changes to the system sudo nixos-rebuild switch --flake .#nixos # Dry-run to check configuration without applying nixos-rebuild build --flake .#nixos # Update system with latest nixpkgs sudo nixos-rebuild switch --upgrade ``` ### Secrets Management ```bash # Generate a new age key for SOPS nix-shell -p age --run "age-keygen -o key.txt" # Edit encrypted secrets nix-shell -p sops --run "sops secrets/secrets.yaml" ``` ### Container Management ```bash # View running containers sudo podman ps # View container logs sudo podman logs # Restart a container service sudo systemctl restart podman-.service ``` ## Architecture ### Module System All services are defined as custom modules under `myModules.` namespace in `modules/`: ``` modules/ ├── default.nix # Imports all modules ├── system.nix # Base system config, packages ├── podman.nix # Container runtime setup ├── nginx.nix # Reverse proxy + ACME ├── searxng.nix # Search engine stack (SearXNG + Valkey + Anubis) └── openclaw-podman.nix # AI agent container ``` ### Module Pattern Each module follows this structure: ```nix { config, lib, pkgs, ... }: let cfg = config.myModules.; in { options.myModules. = { ... }; config = lib.mkIf cfg.enable { ... }; } ``` Modules are enabled/configured in `configuration.nix`: ```nix myModules.searxng = { enable = true; port = 8888; domain = "search.example.com"; }; ``` ### Secrets (SOPS) - Secrets defined in `secrets/secrets.yaml` (encrypted) - SOPS configuration in `.sops.yaml` - Secrets are injected into containers via environment files: - `sops.templates."service.env"` creates env file with interpolated secrets - Container references: `environmentFiles = [ config.sops.templates."service.env".path ]` ### Container Networking - SearXNG uses a dedicated podman network (`searxng-net`) - Services bind to `127.0.0.1` only; Nginx handles external traffic - OpenClaw uses `--network=host` for Discord gateway access ### Service Dependencies Modules declare dependencies explicitly: ```nix config = lib.mkIf cfg.enable { myModules.podman.enable = true; # Ensures podman is enabled ... }; ```