rootless-docker-opensearch-ulimits-memlock
Done. Solution written to ~/rootless-docker-opensearch-ulimits-memlock.md.
Root cause: RLIMIT_MEMLOCK is rlimit type 8. The bunker compose sets memlock: {soft: -1, hard: -1} (unlimited). A rootless runtime runs unprivileged, and setting a hard rlimit above its inherited hard limit requires CAP_SYS_RESOURCE — so container creation fails with EPERM before the container ever starts. Rootful dockerd still has the privilege, which is why the main compose keeps -1.
Fix (as per commit 9770a65): in deploy/bunker/docker-compose.bunker.yml only — bootstrap.memory_lock: "false", memlock soft/hard: 65536 (finite, ≥ the default 64 KiB unprivileged hard limit, so always settable), nofile: 65536 unchanged, and cap heap with OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m.
Verification performed here:
1. Syscall proof — as an unprivileged user, setrlimit(RLIMIT_MEMLOCK, {-1,-1}) fails with exactly "Operation not permitted" (the container's error); finite 65536 succeeds.
2. Compose proof — reconstructed the file in a /tmp/bunker-mirror (compose at deploy/bunker/, .env at root, matching real relative layout), ran the required docker compose config -q (compose 2.40.3): exit 0, rendered config shows bootstrap.memory_lock: "false", memlock soft/hard: 65536/65536, OPENSEARCH_JAVA_OPTS: -Xms512m -Xmx512m, nofile: 65536 intact.
Note documented in the write-up: config -q alone would pass even for the broken file (it's a parse check), so the doc includes the rlimit syscall evidence as the independent guarantee, plus the warning to never compose up the bunker file locally due to container_name: dexdat-* collisions.
# Evidence - Problem class: rootless-docker-opensearch-ulimits-memlock - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-18T17:08:45.585Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "OpenSearch container in docker-compose fails to start in ROOTLESS Docker with 'error setting rlimit type 8: operation not permitted' (container never starts, compose up aborts, every redeploy breaks). Root cause: compose sets bootstrap.memory_lock: \"true\" with ulimits memlock soft/hard: -1 (unlimited) \u2014 rootless dockerd cannot set memlock to unlimited. FIX (proven on a rootless bunker agent, applied to deploy/bunker/docker-compose.bunker.yml commit 9770a65): set bootstrap.memory_lock: \"false\" and memlock soft/hard: 65536 (finite value); keep nofile 65536 as-is; cap heap via OPENSEARCH_JAVA_OPTS -Xms512m -Xmx512m. Main rootful compose can keep -1; only rootless deployments need the change. Validate with: cp <compose> + root .env to a /tmp mirror (env_file resolves relative to compose file dir), then 'docker compose -f docker-compose.bunker.yml config -q'. Do NOT docker compose up the bunker file locally (container_name: dexdat-* collides with the main stack).", "environment": "", "language": "yaml", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "rootless-docker-opensearch-ulimits-memlock", "provider": "openrouter", "solved_at": "2026-08-18T17:08:45.586Z", "version": ""}Done. Solution written to ~/rootless-docker-opensearch-ulimits-memlock.md.
Root cause: RLIMIT_MEMLOCK is rlimit type 8. The bunker compose sets memlock: {soft: -1, hard: -1} (unlimited). A rootless runtime runs unprivileged, and setting a hard rlimit above its inherited hard limit requires CAP_SYS_RESOURCE — so container creation fails with EPERM before the container ever starts. Rootful dockerd still has the privilege, which is why the main compose keeps -1.
Fix (as per commit 9770a65): in deploy/bunker/docker-compose.bunker.yml only — bootstrap.memory_lock: "false", memlock soft/hard: 65536 (finite, ≥ the default 64 KiB unprivileged hard limit, so always settable), nofile: 65536 unchanged, and cap heap with OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m.
Verification performed here:
1. Syscall proof — as an unprivileged user, setrlimit(RLIMIT_MEMLOCK, {-1,-1}) fails with exactly "Operation not permitted" (the container's error); finite 65536 succeeds.
2. Compose proof — reconstructed the file in a /tmp/bunker-mirror (compose at deploy/bunker/, .env at root, matching real relative layout), ran the required docker compose config -q (compose 2.40.3): exit 0, rendered config shows bootstrap.memory_lock: "false", memlock soft/hard: 65536/65536, OPENSEARCH_JAVA_OPTS: -Xms512m -Xmx512m, nofile: 65536 intact.
Note documented in the write-up: config -q alone would pass even for the broken file (it's a parse check), so the doc includes the rlimit syscall evidence as the independent guarantee, plus the warning to never compose up the bunker file locally due to container_name: dexdat-* collisions.
# Evidence - Problem class: rootless-docker-opensearch-ulimits-memlock - Model: openrouter/deepseek/deepseek-v4-flash-0731 - Solved: 2026-08-18T17:08:45.585Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "OpenSearch container in docker-compose fails to start in ROOTLESS Docker with 'error setting rlimit type 8: operation not permitted' (container never starts, compose up aborts, every redeploy breaks). Root cause: compose sets bootstrap.memory_lock: \"true\" with ulimits memlock soft/hard: -1 (unlimited) \u2014 rootless dockerd cannot set memlock to unlimited. FIX (proven on a rootless bunker agent, applied to deploy/bunker/docker-compose.bunker.yml commit 9770a65): set bootstrap.memory_lock: \"false\" and memlock soft/hard: 65536 (finite value); keep nofile 65536 as-is; cap heap via OPENSEARCH_JAVA_OPTS -Xms512m -Xmx512m. Main rootful compose can keep -1; only rootless deployments need the change. Validate with: cp <compose> + root .env to a /tmp mirror (env_file resolves relative to compose file dir), then 'docker compose -f docker-compose.bunker.yml config -q'. Do NOT docker compose up the bunker file locally (container_name: dexdat-* collides with the main stack).", "environment": "", "language": "yaml", "model": "openrouter/deepseek/deepseek-v4-flash-0731", "problem_class": "rootless-docker-opensearch-ulimits-memlock", "provider": "openrouter", "solved_at": "2026-08-18T17:08:45.586Z", "version": ""}