Problem with starting pm2 app in symlinked directories
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 43.3k
- Forks
- 2.7k
- PR merge metrics
- No merged PRs in 30d
Description
I found https://github.com/Unitech/pm2/issues/1663 and while it is closed and seems resolved, the fundamental problem lives on.
In our experience there's a problem with resolving symlinks with pm2, take our example when using DeployHQ (I guess it applies to any deployment service that uses an atomic or zero-downtime deployment based on symlinks) to deploy a Next.js app (but any type of app will have the same problem) that is restarted with pm2.
Assume our deployment path is /var/www/example.com, and zero-downtime option is enabled. This means that the directory structure is like this:
$ ls -l /var/www/example.com
lrwxrwxrwx 1 next next 25 Jan 17 13:24 current -> ./releases/20250117122009
drwxr-xr-x 4 next next 4096 Jan 17 13:24 releases
drwxr-xr-x 2 next next 4096 Jan 15 18:23 shared
Now I navigate to the "current" path: cd /var/www/example.com/current
And run : pm2 start npm --name nextjs-app -- run start
Assume that the app is running correctly, I would run pm2 save to dump the state and allow pm2 startup to start the app on boot.
If I run pm2 show nextjs-app here's a truncated result:
┌───────────────────┬────────────────────────────────────────────────────────┐
│ status │ online │
│ name │ nextjs-app │
│ script path │ /usr/bin/npm │
│ script args │ run start │
│ interpreter │ node │
│ interpreter args │ N/A │
│ exec cwd │ /var/www/example.com/releases/20250117122009 │
│ exec mode │ fork_mode │
│ node.js version │ 20.17.0 │
│ node env │ N/A │
└───────────────────┴────────────────────────────────────────────────────────┘
Notice how the exec cwd is not the current symlink directory, but it has been resolved to the release subdirectory.
If I inspect the file ~/.pm2/dump.pm2, I find the problem:
[...]
"pm_exec_path": "/usr/bin/npm",
"pm_cwd": "/var/www/example.com/releases/20250117122009",
[...]
"PWD": "/var/www/example.com/current",
[...]
At next deployment, when the app is restarted (an SSH command with pm2 restart is issued) the app will be restarted in the old directory, meaning the new version is not used. Furthermore, after a number of deployments (specifically one more that the Atomic Retention value, in our case it's 2) the app will not start because the deployment service has deleted the original release when the app has been started.
Our workaround is to edit the dump file, setting pm_cwd to /var/www/example.com/current, and then run pm2 kill and pm2 resurrect.
$ pm2 -v
5.4.2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the deployment flow with pm2 start, pm2 save, and pm2 restart from /var/www/example.com/current, then inspect ~/.pm2/dump.pm2 and the reported pm_cwd value. Done means restarting after the symlink moves uses the current release rather than the deleted release directory, including after pm2 kill and pm2 resurrect.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- cli, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100