mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 15:47:28 +00:00
fix(docker): persist auth profile key mount
This commit is contained in:
@@ -38,6 +38,7 @@ services:
|
||||
volumes:
|
||||
- ${OPENCLAW_CONFIG_DIR:-${HOME:-/tmp}/.openclaw}:/home/node/.openclaw
|
||||
- ${OPENCLAW_WORKSPACE_DIR:-${HOME:-/tmp}/.openclaw/workspace}:/home/node/.openclaw/workspace
|
||||
- ${OPENCLAW_AUTH_PROFILE_SECRET_DIR:-${HOME:-/tmp}/.openclaw-auth-profile-secrets}:/home/node/.config/openclaw
|
||||
## Uncomment the lines below to enable sandbox isolation
|
||||
## (agents.defaults.sandbox). Requires Docker CLI in the image
|
||||
## (build with --build-arg OPENCLAW_INSTALL_DOCKER_CLI=1) or use
|
||||
@@ -112,6 +113,7 @@ services:
|
||||
volumes:
|
||||
- ${OPENCLAW_CONFIG_DIR:-${HOME:-/tmp}/.openclaw}:/home/node/.openclaw
|
||||
- ${OPENCLAW_WORKSPACE_DIR:-${HOME:-/tmp}/.openclaw/workspace}:/home/node/.openclaw/workspace
|
||||
- ${OPENCLAW_AUTH_PROFILE_SECRET_DIR:-${HOME:-/tmp}/.openclaw-auth-profile-secrets}:/home/node/.config/openclaw
|
||||
stdin_open: true
|
||||
tty: true
|
||||
init: true
|
||||
|
||||
@@ -240,9 +240,11 @@ fi
|
||||
|
||||
OPENCLAW_CONFIG_DIR="${OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}"
|
||||
OPENCLAW_WORKSPACE_DIR="${OPENCLAW_WORKSPACE_DIR:-$HOME/.openclaw/workspace}"
|
||||
OPENCLAW_AUTH_PROFILE_SECRET_DIR="${OPENCLAW_AUTH_PROFILE_SECRET_DIR:-$HOME/.openclaw-auth-profile-secrets}"
|
||||
|
||||
validate_mount_path_value "OPENCLAW_CONFIG_DIR" "$OPENCLAW_CONFIG_DIR"
|
||||
validate_mount_path_value "OPENCLAW_WORKSPACE_DIR" "$OPENCLAW_WORKSPACE_DIR"
|
||||
validate_mount_path_value "OPENCLAW_AUTH_PROFILE_SECRET_DIR" "$OPENCLAW_AUTH_PROFILE_SECRET_DIR"
|
||||
if [[ -n "$HOME_VOLUME_NAME" ]]; then
|
||||
if [[ "$HOME_VOLUME_NAME" == *"/"* ]]; then
|
||||
validate_mount_path_value "OPENCLAW_HOME_VOLUME" "$HOME_VOLUME_NAME"
|
||||
@@ -270,6 +272,7 @@ fi
|
||||
|
||||
mkdir -p "$OPENCLAW_CONFIG_DIR"
|
||||
mkdir -p "$OPENCLAW_WORKSPACE_DIR"
|
||||
mkdir -p "$OPENCLAW_AUTH_PROFILE_SECRET_DIR"
|
||||
# Seed directory tree eagerly so bind mounts work even on Docker Desktop/Windows
|
||||
# where the container (even as root) cannot create new host subdirectories.
|
||||
mkdir -p "$OPENCLAW_CONFIG_DIR/identity"
|
||||
@@ -278,6 +281,7 @@ mkdir -p "$OPENCLAW_CONFIG_DIR/agents/main/sessions"
|
||||
|
||||
export OPENCLAW_CONFIG_DIR
|
||||
export OPENCLAW_WORKSPACE_DIR
|
||||
export OPENCLAW_AUTH_PROFILE_SECRET_DIR
|
||||
export OPENCLAW_GATEWAY_PORT="${OPENCLAW_GATEWAY_PORT:-18789}"
|
||||
export OPENCLAW_BRIDGE_PORT="${OPENCLAW_BRIDGE_PORT:-18790}"
|
||||
export OPENCLAW_GATEWAY_BIND="${OPENCLAW_GATEWAY_BIND:-lan}"
|
||||
@@ -343,6 +347,7 @@ write_extra_compose() {
|
||||
local gateway_home_mount
|
||||
local gateway_config_mount
|
||||
local gateway_workspace_mount
|
||||
local gateway_auth_profile_secret_mount
|
||||
|
||||
cat >"$EXTRA_COMPOSE_FILE" <<'YAML'
|
||||
services:
|
||||
@@ -354,12 +359,15 @@ YAML
|
||||
gateway_home_mount="${home_volume}:/home/node"
|
||||
gateway_config_mount="${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw"
|
||||
gateway_workspace_mount="${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace"
|
||||
gateway_auth_profile_secret_mount="${OPENCLAW_AUTH_PROFILE_SECRET_DIR}:/home/node/.config/openclaw"
|
||||
validate_mount_spec "$gateway_home_mount"
|
||||
validate_mount_spec "$gateway_config_mount"
|
||||
validate_mount_spec "$gateway_workspace_mount"
|
||||
validate_mount_spec "$gateway_auth_profile_secret_mount"
|
||||
printf ' - %s\n' "$gateway_home_mount" >>"$EXTRA_COMPOSE_FILE"
|
||||
printf ' - %s\n' "$gateway_config_mount" >>"$EXTRA_COMPOSE_FILE"
|
||||
printf ' - %s\n' "$gateway_workspace_mount" >>"$EXTRA_COMPOSE_FILE"
|
||||
printf ' - %s\n' "$gateway_auth_profile_secret_mount" >>"$EXTRA_COMPOSE_FILE"
|
||||
fi
|
||||
|
||||
for mount in "$@"; do
|
||||
@@ -376,6 +384,7 @@ YAML
|
||||
printf ' - %s\n' "$gateway_home_mount" >>"$EXTRA_COMPOSE_FILE"
|
||||
printf ' - %s\n' "$gateway_config_mount" >>"$EXTRA_COMPOSE_FILE"
|
||||
printf ' - %s\n' "$gateway_workspace_mount" >>"$EXTRA_COMPOSE_FILE"
|
||||
printf ' - %s\n' "$gateway_auth_profile_secret_mount" >>"$EXTRA_COMPOSE_FILE"
|
||||
fi
|
||||
|
||||
for mount in "$@"; do
|
||||
@@ -473,6 +482,7 @@ upsert_env() {
|
||||
upsert_env "$ENV_FILE" \
|
||||
OPENCLAW_CONFIG_DIR \
|
||||
OPENCLAW_WORKSPACE_DIR \
|
||||
OPENCLAW_AUTH_PROFILE_SECRET_DIR \
|
||||
OPENCLAW_GATEWAY_PORT \
|
||||
OPENCLAW_BRIDGE_PORT \
|
||||
OPENCLAW_GATEWAY_BIND \
|
||||
@@ -532,6 +542,7 @@ echo "==> Fixing data-directory permissions"
|
||||
# (.openclaw/) inside the workspace gets chowned, not the user's project files.
|
||||
run_prestart_gateway --user root --entrypoint sh openclaw-gateway -c \
|
||||
'find /home/node/.openclaw -xdev -exec chown node:node {} +; \
|
||||
find /home/node/.config/openclaw -xdev -exec chown node:node {} +; \
|
||||
[ -d /home/node/.openclaw/workspace/.openclaw ] && chown -R node:node /home/node/.openclaw/workspace/.openclaw || true'
|
||||
|
||||
echo ""
|
||||
|
||||
@@ -104,6 +104,7 @@ function createEnv(
|
||||
OPENCLAW_GATEWAY_TOKEN: "test-token",
|
||||
OPENCLAW_CONFIG_DIR: join(sandbox.rootDir, "config"),
|
||||
OPENCLAW_WORKSPACE_DIR: join(sandbox.rootDir, "openclaw"),
|
||||
OPENCLAW_AUTH_PROFILE_SECRET_DIR: join(sandbox.rootDir, "auth-profile-secrets"),
|
||||
};
|
||||
|
||||
for (const [key, value] of Object.entries(overrides)) {
|
||||
@@ -258,11 +259,17 @@ describe("scripts/docker/setup.sh", () => {
|
||||
expect(envFile).toContain("OPENCLAW_EXTRA_MOUNTS=");
|
||||
expect(envFile).toContain("OPENCLAW_HOME_VOLUME=openclaw-home"); // pragma: allowlist secret
|
||||
expect(envFile).toContain("OPENCLAW_DISABLE_BONJOUR=");
|
||||
expect(envFile).toContain(
|
||||
`OPENCLAW_AUTH_PROFILE_SECRET_DIR=${join(activeSandbox.rootDir, "auth-profile-secrets")}`,
|
||||
);
|
||||
const extraCompose = await readFile(
|
||||
join(activeSandbox.rootDir, "docker-compose.extra.yml"),
|
||||
"utf8",
|
||||
);
|
||||
expect(extraCompose).toContain("openclaw-home:/home/node");
|
||||
expect(extraCompose).toContain(
|
||||
`${join(activeSandbox.rootDir, "auth-profile-secrets")}:/home/node/.config/openclaw`,
|
||||
);
|
||||
expect(extraCompose).toContain("volumes:");
|
||||
expect(extraCompose).toContain("openclaw-home:");
|
||||
const log = await readDockerLog(activeSandbox);
|
||||
@@ -383,6 +390,27 @@ describe("scripts/docker/setup.sh", () => {
|
||||
expect(log).toContain("run --rm --no-deps --user root --entrypoint sh openclaw-gateway -c");
|
||||
});
|
||||
|
||||
it("precreates auth profile secret key dir outside the mounted state dir", async () => {
|
||||
const activeSandbox = requireSandbox(sandbox);
|
||||
const configDir = join(activeSandbox.rootDir, "config-auth-profile-key");
|
||||
const workspaceDir = join(activeSandbox.rootDir, "workspace-auth-profile-key");
|
||||
const secretDir = join(activeSandbox.rootDir, "auth-profile-secret-key");
|
||||
|
||||
const result = runDockerSetup(activeSandbox, {
|
||||
OPENCLAW_CONFIG_DIR: configDir,
|
||||
OPENCLAW_WORKSPACE_DIR: workspaceDir,
|
||||
OPENCLAW_AUTH_PROFILE_SECRET_DIR: secretDir,
|
||||
});
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
const secretDirStat = await stat(secretDir);
|
||||
expect(secretDirStat.isDirectory()).toBe(true);
|
||||
expect(secretDir.startsWith(`${configDir}/`)).toBe(false);
|
||||
|
||||
const log = await readDockerLog(activeSandbox);
|
||||
expect(log).toContain("find /home/node/.config/openclaw -xdev");
|
||||
});
|
||||
|
||||
it("reuses existing config token when OPENCLAW_GATEWAY_TOKEN is unset", async () => {
|
||||
const activeSandbox = requireSandbox(sandbox);
|
||||
const { result, envFile } = await runDockerSetupWithUnsetGatewayToken(
|
||||
@@ -645,6 +673,15 @@ describe("scripts/docker/setup.sh", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps docker-compose auth profile secret key source durable outside state", async () => {
|
||||
const compose = await readFile(join(repoRoot, "docker-compose.yml"), "utf8");
|
||||
expect(
|
||||
compose.split(
|
||||
"${OPENCLAW_AUTH_PROFILE_SECRET_DIR:-${HOME:-/tmp}/.openclaw-auth-profile-secrets}:/home/node/.config/openclaw",
|
||||
),
|
||||
).toHaveLength(3);
|
||||
});
|
||||
|
||||
it("keeps docker-compose optional env files aligned across services", async () => {
|
||||
const compose = await readFile(join(repoRoot, "docker-compose.yml"), "utf8");
|
||||
expect(compose.match(/env_file:\n {6}- path: \.env\n {8}required: false/g)).toHaveLength(2);
|
||||
|
||||
Reference in New Issue
Block a user