nixos-vps/modules/openclaw.nix

112 lines
2.8 KiB
Nix

# OpenClaw Module
# Provides: AI Agent with Discord integration
#
# Usage:
# myModules.openclaw = {
# enable = true;
# port = 18789;
# };
{
config,
lib,
pkgs,
...
}:
let
cfg = config.myModules.openclaw;
configDir = "/var/lib/openclaw/config";
dataDir = "/var/lib/openclaw/data";
workspaceDir = "/var/lib/openclaw/workspace";
in
{
options.myModules.openclaw = {
enable = lib.mkEnableOption "OpenClaw AI Agent";
port = lib.mkOption {
type = lib.types.port;
default = 18789;
description = "Gateway port for OpenClaw";
};
environmentFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "Path to environment file with API keys";
};
};
config = lib.mkIf cfg.enable {
# Create user for openclaw
users.users.openclaw = {
isSystemUser = true;
group = "openclaw";
home = "/var/lib/openclaw";
createHome = true;
};
users.groups.openclaw = { };
# Create directories
systemd.tmpfiles.settings."10-openclaw" = {
"${configDir}".d = {
user = "openclaw";
group = "openclaw";
mode = "0700";
};
"${dataDir}".d = {
user = "openclaw";
group = "openclaw";
mode = "0700";
};
"${workspaceDir}".d = {
user = "openclaw";
group = "openclaw";
mode = "0700";
};
};
# Copy config file
environment.etc."openclaw/openclaw.json".source = ./openclaw-config.json;
# Systemd service
systemd.services.openclaw = {
description = "OpenClaw AI Agent";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
User = "openclaw";
Group = "openclaw";
WorkingDirectory = dataDir;
Environment = [
"NODE_ENV=production"
"OPENCLAW_CONFIG_DIR=${configDir}"
"OPENCLAW_DATA_DIR=${dataDir}"
"OPENCLAW_WORKSPACE_DIR=${workspaceDir}"
"PATH=${pkgs.nodejs_22}/bin:${pkgs.git}/bin:${pkgs.bash}/bin:${pkgs.coreutils}/bin"
];
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
ExecStartPre = [
"${pkgs.coreutils}/bin/mkdir -p ${configDir} ${dataDir} ${workspaceDir}"
"${pkgs.bash}/bin/bash -c 'cp -n /etc/openclaw/openclaw.json ${configDir}/ || true'"
];
ExecStart = "${pkgs.nodejs_22}/bin/npx openclaw gateway --port ${toString cfg.port} --allow-unconfigured";
Restart = "on-failure";
RestartSec = "10s";
# Security
PrivateTmp = true;
ProtectSystem = "strict";
ReadWritePaths = [ "/var/lib/openclaw" configDir dataDir workspaceDir ];
NoNewPrivileges = true;
};
};
};
}