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