mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-07-09 17:08:29 +00:00
Raise Docker open file limit at startup
Raise the runtime container soft nofile limit before supervisord starts so WebUI and managed services inherit a larger descriptor allowance. Add an explicit compose nofile example, document the startup contract, and cover the limit raise and hard-limit cap with focused regression tests.
This commit is contained in:
parent
1d90c27f3b
commit
68c31b51e1
4 changed files with 107 additions and 0 deletions
|
|
@ -21,6 +21,7 @@
|
|||
- Keep the two-runtime Python model aligned with the root contract.
|
||||
- Do not bake secrets, local `.env` values, or user data into the image.
|
||||
- Runtime startup must ensure `/a0/usr/uploads` exists before supervised services start.
|
||||
- Runtime startup raises the soft open-file limit toward `A0_NOFILE_LIMIT` (default `65535`) before supervisord starts, bounded by the container hard limit.
|
||||
|
||||
## Work Guidance
|
||||
|
||||
|
|
|
|||
|
|
@ -6,5 +6,9 @@ services:
|
|||
- ./agent-zero:/a0
|
||||
ports:
|
||||
- "50080:80"
|
||||
ulimits:
|
||||
nofile:
|
||||
soft: 65535
|
||||
hard: 65535
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,43 @@ if [ -z "$1" ]; then
|
|||
fi
|
||||
BRANCH="$1"
|
||||
|
||||
raise_open_file_limit() {
|
||||
local requested="${A0_NOFILE_LIMIT:-65535}"
|
||||
local soft
|
||||
local hard
|
||||
local target
|
||||
|
||||
if ! [[ "$requested" =~ ^[0-9]+$ ]] || [ "$requested" -lt 1 ]; then
|
||||
echo "Warning: invalid A0_NOFILE_LIMIT='$requested'; keeping open file limit at $(ulimit -S -n)." >&2
|
||||
return
|
||||
fi
|
||||
|
||||
soft="$(ulimit -S -n)"
|
||||
hard="$(ulimit -H -n)"
|
||||
|
||||
if [ "$soft" = "unlimited" ]; then
|
||||
echo "Open file limit is already unlimited."
|
||||
return
|
||||
fi
|
||||
|
||||
target="$requested"
|
||||
if [ "$hard" != "unlimited" ] && [ "$target" -gt "$hard" ]; then
|
||||
target="$hard"
|
||||
fi
|
||||
|
||||
if [ "$target" -gt "$soft" ]; then
|
||||
if ulimit -S -n "$target"; then
|
||||
echo "Raised open file soft limit from $soft to $(ulimit -S -n) (hard: $hard)."
|
||||
else
|
||||
echo "Warning: failed to raise open file soft limit from $soft to $target (hard: $hard)." >&2
|
||||
fi
|
||||
else
|
||||
echo "Open file soft limit is $soft (target: $requested, hard: $hard)."
|
||||
fi
|
||||
}
|
||||
|
||||
raise_open_file_limit
|
||||
|
||||
# Copy all contents from persistent /per to root directory (/) without overwriting
|
||||
cp -r --no-preserve=ownership,mode /per/* /
|
||||
|
||||
|
|
|
|||
65
tests/test_docker_initialize_limits.py
Normal file
65
tests/test_docker_initialize_limits.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import re
|
||||
import resource
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
INITIALIZE_SCRIPT = REPO_ROOT / "docker" / "run" / "fs" / "exe" / "initialize.sh"
|
||||
|
||||
|
||||
def _raise_limit_function() -> str:
|
||||
text = INITIALIZE_SCRIPT.read_text(encoding="utf-8")
|
||||
match = re.search(r"^raise_open_file_limit\(\) \{\n.*?^\}\n", text, re.M | re.S)
|
||||
assert match, "initialize.sh must define raise_open_file_limit"
|
||||
return match.group(0)
|
||||
|
||||
|
||||
def _run_bash(script: str) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(
|
||||
["bash", "-c", script],
|
||||
check=True,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
)
|
||||
|
||||
|
||||
def test_initialize_raises_soft_open_file_limit_to_requested_target():
|
||||
function = _raise_limit_function()
|
||||
|
||||
result = _run_bash(
|
||||
f"""
|
||||
set -euo pipefail
|
||||
{function}
|
||||
ulimit -S -n 1024
|
||||
A0_NOFILE_LIMIT=4096
|
||||
raise_open_file_limit
|
||||
test "$(ulimit -S -n)" = "4096"
|
||||
"""
|
||||
)
|
||||
|
||||
assert "Raised open file soft limit from 1024 to 4096" in result.stdout
|
||||
|
||||
|
||||
def test_initialize_caps_open_file_limit_at_hard_limit():
|
||||
_soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
|
||||
if hard != resource.RLIM_INFINITY and hard < 2048:
|
||||
pytest.skip("host hard open-file limit is too low for this regression test")
|
||||
|
||||
function = _raise_limit_function()
|
||||
|
||||
result = _run_bash(
|
||||
f"""
|
||||
set -euo pipefail
|
||||
{function}
|
||||
ulimit -S -n 1024
|
||||
ulimit -H -n 2048
|
||||
A0_NOFILE_LIMIT=65535
|
||||
raise_open_file_limit
|
||||
test "$(ulimit -S -n)" = "2048"
|
||||
"""
|
||||
)
|
||||
|
||||
assert "Raised open file soft limit from 1024 to 2048" in result.stdout
|
||||
Loading…
Add table
Add a link
Reference in a new issue