diff --git a/README.md b/README.md index 3a729489c8..e6b82b94f3 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,10 @@ $ pm2 start app.json # Start processes with options declared in a $ pm2 start app.js -i max -- -a 23 # Pass arguments after -- to app.js $ pm2 start app.js -i max -e err.log -o out.log # Will start and generate a configuration file + +$ pm2 --run-as-user foo start app.js # Start app.js as user foo instead of root (pm2 must be running as root) + +$ pm2 --run-as-user foo --run-as-group bar start app.js # Start app.js as foo:bar instead of root:root (pm2 must be running as root) ``` You can also execute app in other languages ([the fork mode](#a23)): diff --git a/bin/pm2 b/bin/pm2 index 3f43f77c65..dc31c03ea7 100755 --- a/bin/pm2 +++ b/bin/pm2 @@ -38,6 +38,8 @@ commander.version(pkg.version) function(val) { return val.split(' '); }) + .option('--run-as-user ', 'The user or uid to run a managed process as') + .option('--run-as-group ', 'The group or gid to run a managed process as') .usage('[cmd] app'); // diff --git a/lib/CLI.js b/lib/CLI.js index 448e39b438..237a58129d 100644 --- a/lib/CLI.js +++ b/lib/CLI.js @@ -43,6 +43,10 @@ CLI.startFile = function(script) { appConf['pid_file'] = commander.pid; if (commander.cron) appConf['cron_restart'] = commander.cron; + if (commander.runAsUser) + appConf['run_as_user'] = commander.runAsUser; + if (commander.runAsGroup) + appConf['run_as_group'] = commander.runAsGroup; if (commander.executeCommand) appConf['exec_mode'] = 'fork_mode'; diff --git a/lib/ProcessContainer.js b/lib/ProcessContainer.js index 3bcdfb46ab..41d56c75b2 100644 --- a/lib/ProcessContainer.js +++ b/lib/ProcessContainer.js @@ -119,6 +119,16 @@ function exec(script, outFile, errFile) { } }); + // if we've been told to run as a different user or group (e.g. because they have fewer + // privileges), switch to that user before importing any third party application code. + if (process.env.run_as_group) { + process.setgid(process.env.run_as_group); + } + + if (process.env.run_as_user) { + process.setuid(process.env.run_as_user); + } + // Get the script & exec require(script); });