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:
ashisgreat22 2026-03-18 01:35:02 +01:00
parent 11a588a4d9
commit a595445bd2
6 changed files with 173 additions and 215 deletions

View file

@ -5,6 +5,6 @@
./podman.nix
./nginx.nix
./searxng.nix
./openclaw.nix
./openclaw-podman.nix
];
}

View file

@ -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
}
]
}
}
}
}

View 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"
];
};
};
}

View file

@ -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;
})
];
};
};
}