# 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 hosted remote machines and a complete `nixosConfigurations.noisebell-do` host for the small DigitalOcean droplet. The module 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"; }; }) ]; }; }; } ``` The production DigitalOcean host in this repo enables the cache, Discord, and RSS services on the existing public domains: - `noisebell.extremist.software` - `discord.noisebell.extremist.software` - `rss-noisebell.extremist.software` After installation, authenticate Tailscale interactively on the host with: ```sh sudo tailscale up --hostname=noisebell-do ``` Redeploy later with: ```sh scripts/deploy-do jet@noisebell-do ``` `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/relay-webhook-secret.age` | Pi + remote | cache authenticates to the Pi relay `/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.