README.md

Remote Services

Cargo workspace with the server-side pieces of Noisebell. Runs on any Linux box.

ServicePortWhat it does
cache-service/3000Polls the Pi, stores the latest state in SQLite, fans out webhooks
rss-service/3002Fetches current status from cache and serves RSS/Atom feeds
discord-bot/3001Posts door status to a Discord channel
zulip-bot/3003Posts door status to a Zulip stream
noisebell-common/—Shared types and helpers

See each service's README for configuration and API docs.

Building

sh
1cargo build --release

Or with Nix:

sh
1nix build .#noisebell-cache
2nix build .#noisebell-rss
3nix build .#noisebell-discord
4nix 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
1{
2 inputs.noisebell.url = "git+https://git.extremist.software/jet/noisebell";
3
4 outputs = { self, nixpkgs, noisebell, ... }: {
5 nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
6 system = "x86_64-linux";
7 modules = [
8 noisebell.nixosModules.default
9 ({ ... }: {
10 services.noisebell-cache = {
11 enable = true;
12 domain = "cache.noisebell.example.com";
13 piAddress = "http://noisebell-pi:80";
14 };
15 services.noisebell-rss = {
16 enable = true;
17 domain = "rss.noisebell.example.com";
18 };
19 services.noisebell-discord = {
20 enable = true;
21 domain = "discord.noisebell.example.com";
22 channelId = "123456789012345678";
23 };
24 })
25 ];
26 };
27 };
28}

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
1sudo tailscale up --hostname=noisebell-do

Redeploy later with:

sh
1scripts/deploy-do jet@noisebell-do

nixosModules.default handles these secrets automatically:

Secret fileDeployed onUsed for
secrets/pi-to-cache-key.agePi + remotePi authenticates to cache /webhook
secrets/cache-to-pi-key.agePi + remotecache authenticates to Pi GET endpoints
secrets/discord-webhook-secret.ageremotecache authenticates to Discord bot /webhook
secrets/relay-webhook-secret.agePi + remotecache authenticates to the Pi relay /webhook
secrets/zulip-webhook-secret.ageremotecache authenticates to Zulip bridge /webhook
secrets/discord-token.ageremoteDiscord bot login
secrets/zulip-api-key.ageremoteZulip 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.