# Remote Services Cargo workspace with the server-side pieces of Noisebell. Runs on any Linux box. | Service | Port | What it does | |---------|------|--------------| | [`cache-service/`](cache-service/) | 3000 | Polls the Pi, stores the latest state in SQLite, fans out webhooks | | [`rss-service/`](rss-service/) | 3002 | Fetches current status from cache and serves RSS/Atom feeds | | [`discord-bot/`](discord-bot/) | 3001 | Posts door status to a Discord channel | | [`zulip-bot/`](zulip-bot/) | 3003 | Posts door status to a Zulip stream | | [`noisebell-common/`](noisebell-common/) | — | Shared types and helpers | See each service's README for configuration and API docs. ## Building ```sh cargo build --release ``` Or with Nix: ```sh nix build .#noisebell-cache nix build .#noisebell-rss nix build .#noisebell-discord nix build .#noisebell-zulip ``` ## NixOS deployment The flake exports a NixOS module for the hosted remote machine. It imports `agenix`, declares the Noisebell secrets from `secrets/*.age`, and wires the cache and Discord services together with sensible defaults. Each service runs as a hardened systemd unit behind Caddy. ```nix { inputs.noisebell.url = "git+https://git.extremist.software/jet/noisebell"; outputs = { self, nixpkgs, noisebell, ... }: { nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { system = "x86_64-linux"; modules = [ noisebell.nixosModules.default ({ ... }: { services.noisebell-cache = { enable = true; domain = "cache.noisebell.example.com"; piAddress = "http://noisebell-pi:80"; }; services.noisebell-rss = { enable = true; domain = "rss.noisebell.example.com"; }; services.noisebell-discord = { enable = true; domain = "discord.noisebell.example.com"; channelId = "123456789012345678"; }; }) ]; }; }; } ``` `nixosModules.default` handles these secrets automatically: | Secret file | Deployed on | Used for | |-------------|-------------|----------| | `secrets/pi-to-cache-key.age` | Pi + remote | Pi authenticates to cache `/webhook` | | `secrets/cache-to-pi-key.age` | Pi + remote | cache authenticates to Pi GET endpoints | | `secrets/discord-webhook-secret.age` | remote | cache authenticates to Discord bot `/webhook` | | `secrets/zulip-webhook-secret.age` | remote | cache authenticates to Zulip bridge `/webhook` | | `secrets/discord-token.age` | remote | Discord bot login | | `secrets/zulip-api-key.age` | remote | Zulip bot API authentication | When `extremist-software` builds a system using the Noisebell flake input, Nix uses the checked-out flake source for that input. The module points `agenix` at encrypted files inside that Noisebell source tree, such as `${inputs.noisebell}/secrets/discord-token.age`. At activation time `agenix` decrypts them locally on the target host into runtime paths like `/run/agenix/noisebell-discord-token`. The service modules then read those local decrypted files when systemd starts them.