OpenClaw on floe is partially declarative:
- Nix manages: package (
openclaw-gateway), systemd system service, env vars - Manual:
~/.openclaw/openclaw.json(models, channels, tokens, plugins, tools, hooks)
The nix-openclaw flake provides a Home Manager module (programs.openclaw) that generates
the config, manages the service, and wires plugins — making everything fully declarative.
- Config reproducibility:
openclaw.jsonis currently hand-edited and not in version control - Nix mode (
OPENCLAW_NIX_MODE=1) treats config as read-only — the module should own it - Plugin/skill management via Nix instead of manual file placement
- Secrets via file references (agenix-compatible) instead of inline JSON
- Atomic rollback of config + package together
- Home Manager on floe — the
nix-openclawmodule is Home Manager, not NixOS. Either extend the homemanager repo to cover floe, or add Home Manager as a NixOS module in this repo's flake (home-manager.nixosModules.home-manager). - Secrets as files — move bot tokens and API keys from inline JSON to files in
/run/agenix/or~/.secrets/(plain files work, agenix is optional).
Option A — standalone Home Manager in homemanager repo:
- Add floe host config alongside madrush
- Add
nix-openclawas flake input home-manager switch --flake .#user@floe
Option B — Home Manager as NixOS module (keeps everything in this repo):
- Add
home-manager.url = "github:nix-community/home-manager/release-24.11"to flake.nix - Import
home-manager.nixosModules.home-managerin configuration.nix - Configure
home-manager.users.userinline
Map the current openclaw.json to programs.openclaw.config:
programs.openclaw = {
enable = true;
config = {
gateway = {
port = 18789;
mode = "local";
bind = "loopback";
auth = {
mode = "token";
# token via file or env var, not inline
};
tailscale.mode = "off";
};
agents.defaults = {
model = {
primary = "anthropic/claude-sonnet-4-6";
fallbacks = [ "anthropic/claude-opus-4-6" ];
};
workspace = "/home/user/.openclaw/workspace";
memorySearch.enabled = false;
contextPruning = { mode = "cache-ttl"; ttl = "1h"; };
compaction.mode = "safeguard";
heartbeat.every = "1h";
maxConcurrent = 4;
subagents.maxConcurrent = 8;
};
tools.web = {
search = {
enabled = true;
provider = "brave";
# apiKey via secrets file
};
fetch.enabled = true;
};
messages.ackReactionScope = "group-mentions";
commands = { native = "auto"; nativeSkills = "auto"; restart = true; ownerDisplay = "raw"; };
session.dmScope = "per-channel-peer";
channels.telegram = {
enabled = true;
dmPolicy = "pairing";
tokenFile = "~/.secrets/openclaw-telegram-token"; # or /run/agenix/...
groupPolicy = "disabled";
streaming = "off";
};
channels.discord = {
enabled = true;
tokenFile = "~/.secrets/openclaw-discord-token";
groupPolicy = "open";
streaming = "off";
};
};
# Workspace documents (already exist on floe)
documents = {
# Point to files in this repo or manage separately
};
};Create secret files on floe (or use agenix for encrypted secrets in git):
mkdir -p ~/.secrets && chmod 700 ~/.secrets
# Telegram bot token
echo -n "8764994861:AAG..." > ~/.secrets/openclaw-telegram-token
# Discord bot token
echo -n "MTQ3NjE4NTY..." > ~/.secrets/openclaw-discord-token
# Brave search API key
echo -n "BSA2qa..." > ~/.secrets/openclaw-brave-api-key
# Gateway auth token
echo -n "b094db..." > ~/.secrets/openclaw-gateway-token
# Anthropic API key (if not already in env)- Remove
services/openclaw.nixfrom this repo (module handles the service) - Remove the import from
configuration.nix - Back up and remove
~/.openclaw/openclaw.json(module generates it) - Rebuild and verify:
openclaw doctor,openclaw status
- Zoho WorkDrive skill: migrate to
customPluginsif a flake exists, otherwise keep manual - Workspace docs (SOUL.md, IDENTITY.md, etc.): manage via
documentsoption or keep in workspace
| openclaw.json path | nix-openclaw option |
|---|---|
gateway.* |
config.gateway.* |
agents.defaults.* |
config.agents.defaults.* |
channels.telegram.botToken |
config.channels.telegram.tokenFile (file path) |
channels.discord.token |
config.channels.discord.tokenFile (file path) |
tools.web.search.apiKey |
config.tools.web.search.apiKeyFile or config.env |
hooks.* |
config.hooks.* |
plugins.* |
plugins / customPlugins / bundledPlugins.* |
- Does
nix-openclawNixOS module exist, or only Home Manager? (README shows HM only) - Can
programs.openclawbe enabled without starting the gateway? (for madrush) - How are workspace docs (SOUL.md, USER.md, etc.) versioned — in this repo or separate?
- Agenix vs plain secret files — worth the complexity for a single-user homelab?
- WorkDrive custom plugin: does it have a flake, or does it need wrapping?