Convert Openclaw to Podman container
- Use official ghcr.io/openclaw/openclaw image - configure via JSON config file - containerized for better isolation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
11a588a4d9
commit
a595445bd2
6 changed files with 173 additions and 215 deletions
|
|
@ -5,6 +5,6 @@
|
|||
./podman.nix
|
||||
./nginx.nix
|
||||
./searxng.nix
|
||||
./openclaw.nix
|
||||
./openclaw-podman.nix
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,96 +0,0 @@
|
|||
{
|
||||
"gateway": {
|
||||
"port": 18789,
|
||||
"bind": "loopback",
|
||||
"trustedProxies": ["::1", "127.0.0.1", "10.88.0.0/16", "10.89.0.0/16"],
|
||||
"auth": {
|
||||
"mode": "none"
|
||||
},
|
||||
"controlUi": {
|
||||
"dangerouslyAllowHostHeaderOriginFallback": true,
|
||||
"allowedOrigins": ["*"]
|
||||
}
|
||||
},
|
||||
"channels": {
|
||||
"whatsapp": {
|
||||
"enabled": false
|
||||
},
|
||||
"discord": {
|
||||
"enabled": true,
|
||||
"groupPolicy": "open",
|
||||
"dmPolicy": "open",
|
||||
"allowFrom": ["*"]
|
||||
}
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "zai/glm-5"
|
||||
},
|
||||
"memorySearch": {
|
||||
"provider": "openai",
|
||||
"model": "nomic-embed-text",
|
||||
"remote": {
|
||||
"baseUrl": "http://localhost:11434/v1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"exec": {
|
||||
"security": "full",
|
||||
"ask": "off"
|
||||
}
|
||||
},
|
||||
"skills": {
|
||||
"entries": {}
|
||||
},
|
||||
"commands": {
|
||||
"native": true,
|
||||
"nativeSkills": "auto",
|
||||
"restart": true,
|
||||
"ownerDisplay": "raw"
|
||||
},
|
||||
"models": {
|
||||
"mode": "merge",
|
||||
"providers": {
|
||||
"zai": {
|
||||
"baseUrl": "https://api.z.ai/api/coding/paas/v4",
|
||||
"apiKey": "${ZAI_API_KEY}",
|
||||
"api": "openai-completions",
|
||||
"models": [
|
||||
{
|
||||
"id": "glm-4.7",
|
||||
"name": "GLM 4.7",
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 131072
|
||||
},
|
||||
{
|
||||
"id": "glm-5",
|
||||
"name": "GLM 5",
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 131072
|
||||
},
|
||||
{
|
||||
"id": "glm-5-turbo",
|
||||
"name": "GLM 5 Turbo",
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 131072
|
||||
},
|
||||
{
|
||||
"id": "glm-4.5-air",
|
||||
"name": "GLM 4.5 Air",
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 131072
|
||||
},
|
||||
{
|
||||
"id": "glm-4.7-flash",
|
||||
"name": "GLM 4.7 Flash",
|
||||
"contextWindow": 128000,
|
||||
"maxTokens": 131072
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
modules/openclaw-podman.nix
Normal file
58
modules/openclaw-podman.nix
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
# OpenClaw Podman Module
|
||||
# Provides: AI Agent with Discord integration running in a 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;
|
||||
|
||||
# OpenClaw container
|
||||
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 = [
|
||||
"${config.sops.templates."openclaw_config.json".path}:/root/.openclaw/config.json:ro"
|
||||
"openclaw-data:/root/.openclaw"
|
||||
];
|
||||
extraOptions = [
|
||||
"--network=host"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
# 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 = lib.mkMerge [
|
||||
{
|
||||
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"
|
||||
];
|
||||
|
||||
ExecStartPre = [
|
||||
"${pkgs.coreutils}/bin/mkdir -p ${configDir} ${dataDir} ${workspaceDir} /var/lib/openclaw/.openclaw"
|
||||
"${pkgs.bash}/bin/bash -c 'cp -n /etc/openclaw/openclaw.json /var/lib/openclaw/.openclaw/openclaw.json || 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" "/var/lib/openclaw/.openclaw" configDir dataDir workspaceDir ];
|
||||
NoNewPrivileges = true;
|
||||
}
|
||||
(lib.mkIf (cfg.environmentFile != null) {
|
||||
EnvironmentFile = cfg.environmentFile;
|
||||
})
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue