Starting PM2 as a non-root user is broken #1321

akloeber opened this Issue May 29, 2015 · 27 comments


None yet

In latest v0.12.15 starting PM2 as a non-root user via the generated startup script does not work anymore.
Steps to reproduce:

root# pm2 startup ubuntu -u someUser
root# /etc/init.d/ start
Starting pm2

  return binding.mkdir(pathModule._makeLong(path),
Error: EACCES, permission denied '/root/.pm2'
    at Object.fs.mkdirSync (fs.js:647:18)
    at Object.CLI.pm2Init (/usr/local/lib/node_modules/pm2/lib/CLI.js:37:8)
    at Object.<anonymous> (/usr/local/lib/node_modules/pm2/bin/pm2:20:5)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

Folder '/root/.pm2' got created by pm2 startup and is owned by root. The existence of this folder is strange by itself because PM2 should be run as someUser and not as root (already described in #933) but at least it worked in v0.12.11.

PM2 v0.12.15
node v0.10.25
Ubuntu 14.04.2 LTS


After some analysis I found the change that breaks the startup script.
Variable PM2_HOME (which has the fix value of /root/.pm2 in the script) is now passed when executing PM2 (that was added recently and does not make much sense when PM2 should not be run as root):

su - $USER -s $shell -c "PATH=$PATH; PM2_HOME=$PM2_HOME $*"

If passing of PM2_HOME is removed (su - $USER -s $shell -c "PATH=$PATH; $*") everything works with v0.12.15.

@dceejay dceejay added a commit to node-red/ that referenced this issue Jun 4, 2015
@dceejay dceejay Add temp note to PM2 docs (re init script error issue) d32d9b4

I solved it for myself by providing a fixed init script like this:



export PATH=/usr/bin:$PATH

get_user_info() {
    echo $(getent passwd ${1:-`whoami`})

get_user_shell() {
    local shell=$(get_user_info $1 | cut -d: -f7)

    if [[ $shell == *"/sbin/nologin" ]] || [[ $shell == "/bin/false" ]] || [[ -z "$shell" ]];

    echo $shell

get_user_home() {
    local home=$(get_user_info $1 | cut -d: -f6)

    echo $home

super() {
    local shell=$(get_user_shell $USER)
    local home=$(get_user_home $USER)/.pm2
    su - $USER -s $shell -c "PATH=$PATH; PM2_HOME=$home $*"


Note: Whitespace is removed automatically in get_user_info by echoing without wrapping expression in quotes, so invoking sedis no more necessary.

tomyam1 commented Aug 28, 2015

Just encountered this issue myself.

The user running pm2 is not a sudoer so when I ran pm2 startup ubuntu, I got this message:

tepez-server@api-server:~$ pm2 startup ubuntu
[PM2] You have to run this command as root. Execute the following command:
      sudo su -c "env PATH=$PATH:/home/tepez-server/.nvm/versions/node/v0.12.7/bin pm2 startup ubuntu -u tepez-server"

When I ran the command suggested by pm2 PM2_HOM in the generated script was invalid:

export PM2_HOME="/root/.pm2"

A simple solution was to add an export for PM2_HOME to the script

sudo su -c "export PM2_HOME=/home/tepez-server/.pm2 && env PATH=$PATH:/home/tepez-server/.nvm/versions/node/XXX/bin pm2 startup ubuntu -u tepez-server"

I think this is the script pm2 should instruct to run.


To fix Error: EACCES, permission denied '/root/.pm2', in /etc/init.d/ change the line

export PM2_HOME="/root/.pm2"


export PM2_HOME="/home/<your_user>/.pm2"

I added to the init script

get_user_home() {
    local home=$(getent passwd ${1:-`whoami`} | cut -d: -f6 | sed -e 's/[[:space:]]*$//')

    if [[ -z "$home" ]];

    echo "$home"

then in super()

super() {
    local shell=$(get_user_shell $USER)
    local home=$(get_user_home $USER)
    su - $USER -s $shell -c "PATH=$PATH; PM2_HOME=$home/.pm2 $*"
cuteboi commented Oct 5, 2015

So, is this going upstream at some point? I was surprised something reported in 2014 (in other reports) still remains in late 2015

cuteboi commented Oct 5, 2015

So, is this going upstream at some point? I was surprised something reported in 2014 (in other reports) still remains in late 2015

Unitech commented Oct 6, 2015

waiting for PR


Where's the equivalent /etc/init.d/ in systemd (on Yocto/Intel Edison board environment)?

rudders commented Nov 26, 2015












Unitech commented Mar 2, 2016

Closing in favor of #1035

@Unitech Unitech closed this Mar 2, 2016

This is still happening on May 2016 and the issue this was 'closed in favor of', has absolutely nothing to do with this issue!

For me, @Telemakhos solution worked.


Boycce commented May 10, 2016

@RafaPolit @Unitech I am confused also?


I'm still having this issue, and I'm not sure how related it is to #1035.
On May 10, 2016 7:43 AM, "Ricky Boyce" wrote:

@RafaPolit @Unitech I am confused also?

You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#1321 (comment)




I'm getting this error for pm2 commands if I don't use sudo:

      throw er; // Unhandled 'error' event

Error: connect EACCES /home/username/.pm2/rpc.sock
    at Object.exports._errnoException (util.js:1022:11)
    at exports._exceptionWithHostPort (util.js:1045:20)
    at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1090:14)

Because the user who launched the daemon isn't the same as the one who trying to connect, you need to review the chmod of the dir to be able to share the daemon.

josephrocca commented Jan 14, 2017 edited

@vmarchaud I've tried full re-installs many times now (npm uninstall + delete persistent pm2 files including ~/.pm2) and the same thing always happens. Any reason why pub.sock and rpc.sock become owned by root? Seems that it only happens after reboot (after fresh install).

-rw-rw-r-- 1 username  username  4329 Jan 14 16:57 dump.pm2
drwxrwxr-x 2 username  username  4096 Jan 14 16:56 logs
-rw-rw-r-- 1 username  username     2 Jan 14 16:55 module_conf.json
drwxrwxr-x 2 username  username  4096 Jan 14 16:57 pids
-rw-rw-r-- 1 username  username  3043 Jan 14 16:57 pm2.log
-rw-rw-r-- 1 username  username     4 Jan 14 16:57
srwxr-xr-x 1 root root    0 Jan 14 16:57 pub.sock
srwxr-xr-x 1 root root    0 Jan 14 16:57 rpc.sock
-rw-rw-r-- 1 username  username    13 Jan 14 16:55 touch

My general pattern has been:

  • full reinstall (with sudo)
  • add app.js
  • pm2 startup
  • reboot (and now I get error if I don't use sudo - before this step I didn't have to)

In any case, I don't mind using sudo but it's just a bit strange/annoying :/


Because the daemon as been started by root user, you need to install and run pm2 as your user.

josephrocca commented Jan 15, 2017 edited

you need to install and run pm2 as your user

I have been. I don't use root (except via sudo, which is needed for installation).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment