Skip to content

Commit 619b967

Browse files
committed
refactor(satellite): improve nsjail configuration comments and structure
1 parent eb44031 commit 619b967

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

services/satellite/src/config/nsjail.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* These limits apply only in production on Linux platforms when nsjail isolation is enabled
44
*
55
* Defaults based on empirical testing with package managers (npm, uvx) and runtime requirements:
6-
* - 2048MB memory: Sufficient for V8, Python interpreters, and other runtimes
6+
* - 2048MB virtual memory (RLIMIT_AS): Fallback for systems without cgroup support
7+
* - 512MB physical memory (cgroup_mem_max): Precise control over actual memory usage
78
* - 1000 processes: Adequate for package managers which spawn many child processes
89
* - 1024 file descriptors: Adequate for file I/O operations
910
* - 50MB file size: Prevents oversized downloads while accommodating most packages
@@ -13,12 +14,18 @@ export const nsjailConfig = {
1314
/** Memory limit per MCP server process in MB (default: 2048, sufficient for most runtimes) */
1415
memoryLimitMB: parseInt(process.env.NSJAIL_MEMORY_LIMIT_MB || '2048', 10),
1516

17+
/** Cgroup physical memory limit in bytes (default: 512MB = 536870912 bytes) */
18+
cgroupMemMaxBytes: parseInt(process.env.NSJAIL_CGROUP_MEM_MAX_BYTES || '536870912', 10),
19+
1620
/** CPU time limit per MCP server process in seconds (default: 60) */
1721
cpuTimeLimitSeconds: parseInt(process.env.NSJAIL_CPU_TIME_LIMIT_SECONDS || '60', 10),
1822

1923
/** Maximum number of processes per MCP server (default: 1000, required for package managers) */
2024
maxProcesses: parseInt(process.env.NSJAIL_MAX_PROCESSES || '1000', 10),
2125

26+
/** Cgroup max PIDs (default: 1000) */
27+
cgroupPidsMax: parseInt(process.env.NSJAIL_CGROUP_PIDS_MAX || '1000', 10),
28+
2229
/** Maximum number of open file descriptors (default: 1024) */
2330
maxOpenFiles: parseInt(process.env.NSJAIL_RLIMIT_NOFILE || '1024', 10),
2431

services/satellite/src/process/nsjail-spawner.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,13 @@ export class ProcessSpawner {
206206
* Spawn process with nsjail isolation (production mode on Linux)
207207
*
208208
* Configuration supports multiple runtimes (Node.js, Python, etc.):
209-
* - Memory: 2048MB (adequate for V8 and Python interpreters)
209+
* - Memory: 2048MB virtual (RLIMIT_AS), 512MB physical (cgroup)
210210
* - Processes: 1000 (package managers spawn many child processes)
211211
* - File descriptors: 1024 (adequate for I/O operations)
212212
* - File size: 50MB (prevents oversized downloads)
213213
* - /dev files: Required for crypto and I/O operations
214214
* - --proc_rw: Required for pthread_create and thread management
215+
* - Cgroup limits: Precise control over physical memory and CPU usage
215216
*/
216217
async spawnWithNsjail(config: MCPServerConfig): Promise<ChildProcess> {
217218
// Determine runtime (default to 'node' for backward compatibility)
@@ -227,12 +228,14 @@ export class ProcessSpawner {
227228
runtime: runtime,
228229
cache_dir: cacheDir,
229230
memory_limit_mb: nsjailConfig.memoryLimitMB,
231+
cgroup_mem_max_mb: Math.floor(nsjailConfig.cgroupMemMaxBytes / (1024 * 1024)),
230232
cpu_time_limit_seconds: nsjailConfig.cpuTimeLimitSeconds,
231233
max_processes: nsjailConfig.maxProcesses,
234+
cgroup_pids_max: nsjailConfig.cgroupPidsMax,
232235
max_open_files: nsjailConfig.maxOpenFiles,
233236
max_file_size_mb: nsjailConfig.maxFileSizeMB,
234237
tmpfs_size: nsjailConfig.tmpfsSize
235-
}, `Spawning ${runtime} MCP server with nsjail isolation`);
238+
}, `Spawning ${runtime} MCP server with nsjail isolation (cgroup mem: 512MB)`);
236239

237240
// Get current user UID and GID (deploystack user in production)
238241
const uid = process.getuid ? process.getuid() : 1000;
@@ -259,6 +262,9 @@ export class ProcessSpawner {
259262
'--rlimit_nofile', String(nsjailConfig.maxOpenFiles), // Max file descriptors
260263
'--rlimit_fsize', String(nsjailConfig.maxFileSizeMB), // Max file size (MB)
261264
'--time_limit', '0', // No wall-clock time limit
265+
// Cgroup limits for precise resource control
266+
'--cgroup_mem_max', String(nsjailConfig.cgroupMemMaxBytes), // Physical memory limit (512MB)
267+
'--cgroup_pids_max', String(nsjailConfig.cgroupPidsMax), // Process limit (1000)
262268
'-R', '/usr', // Read-only mount: /usr
263269
'-R', '/lib', // Read-only mount: /lib
264270
'-R', '/lib64', // Read-only mount: /lib64

0 commit comments

Comments
 (0)