# OpenClaw Podman Module # Provides: AI Agent with Discord integration running in an isolated container # # Usage: # myModules.openclaw-podman = { # enable = true; # port = 18789; # domain = "openclaw.example.com"; # }; { config, lib, pkgs, ... }: let cfg = config.myModules.openclaw-podman; in { options.myModules.openclaw-podman = { enable = lib.mkEnableOption "OpenClaw AI Agent (Podman)"; port = lib.mkOption { type = lib.types.port; default = 18789; description = "Gateway port for OpenClaw"; }; domain = lib.mkOption { type = lib.types.str; example = "openclaw.example.com"; description = "Public domain for OpenClaw"; }; }; config = lib.mkIf cfg.enable { # Enable podman myModules.podman.enable = true; # Create directory for OpenClaw data systemd.tmpfiles.rules = [ "d /var/lib/openclaw 0755 1000 1000 -" # Assuming node user is uid 1000 ]; # OpenClaw container (bridge network — isolated from host services) virtualisation.oci-containers.containers."openclaw" = { image = "ghcr.io/openclaw/openclaw:latest"; ports = [ "127.0.0.1:${toString cfg.port}:8080" ]; environmentFiles = [ config.sops.templates."openclaw.env".path ]; volumes = [ "/var/lib/openclaw:/home/node/.openclaw" ]; }; # Copy the declarative config before starting the container # This allows OpenClaw to safely write/rename the file at runtime without EBUSY errors systemd.services."podman-openclaw".preStart = lib.mkBefore '' mkdir -p /var/lib/openclaw cp -f ${./openclaw-config.json} /var/lib/openclaw/openclaw.json chown -R 1000:1000 /var/lib/openclaw chmod -R u+rwX /var/lib/openclaw ''; }; }