[{"data":1,"prerenderedAt":1550},["ShallowReactive",2],{"page-en-\u002Fblog\u002Ffrequently-used-pm2-commands":3},{"id":4,"title":5,"body":6,"date":1538,"description":1539,"extension":1540,"meta":1541,"navigation":464,"path":1542,"seo":1543,"stem":1544,"tags":1545,"translation":1548,"__hash__":1549},"pages_en\u002Fen\u002Fblog\u002Ffrequently-used-pm2-commands.md","Frequently Used PM2 Commands",{"type":7,"value":8,"toc":1524},"minimark",[9,14,25,46,50,53,90,97,120,124,259,262,342,346,393,403,407,492,567,571,586,676,683,743,747,750,836,846,850,853,871,1145,1209,1212,1216,1225,1263,1267,1270,1304,1311,1339,1352,1356,1405,1408,1478,1482,1520],[10,11,13],"h2",{"id":12},"introduction","Introduction",[15,16,17,24],"p",{},[18,19,23],"a",{"href":20,"rel":21},"https:\u002F\u002Fpm2.keymetrics.io\u002F",[22],"nofollow","PM2"," is a process manager for Node.js applications. It runs your app in the background, restarts it when it crashes, collects its logs, spreads it across multiple CPU cores and brings your apps back when the server reboots. It isn't limited to Node.js either — it can manage Python, Bash or any other executable.",[15,26,27,28,32,33,37,38,41,42,45],{},"This post collects the PM2 commands you need most in day-to-day work, in order of use. The examples use ",[29,30,31],"code",{},"api"," as the app name; in any command you can use the ",[34,35,36],"strong",{},"id"," from ",[29,39,40],{},"pm2 list"," instead of the name, or ",[29,43,44],{},"all"," for every app.",[10,47,49],{"id":48},"_1-installation","1. Installation",[15,51,52],{},"PM2 is installed globally:",[54,55,60],"pre",{"className":56,"code":57,"language":58,"meta":59,"style":59},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npm install -g pm2\npm2 --version\n","bash","",[29,61,62,81],{"__ignoreMap":59},[63,64,67,71,75,78],"span",{"class":65,"line":66},"line",1,[63,68,70],{"class":69},"sBMFI","npm",[63,72,74],{"class":73},"sfazB"," install",[63,76,77],{"class":73}," -g",[63,79,80],{"class":73}," pm2\n",[63,82,84,87],{"class":65,"line":83},2,[63,85,86],{"class":69},"pm2",[63,88,89],{"class":73}," --version\n",[15,91,92,93,96],{},"After upgrading PM2, run ",[29,94,95],{},"pm2 update"," so the background daemon switches to the new version too; running apps are saved and brought back up.",[54,98,100],{"className":56,"code":99,"language":58,"meta":59,"style":59},"npm install -g pm2@latest\npm2 update\n",[29,101,102,113],{"__ignoreMap":59},[63,103,104,106,108,110],{"class":65,"line":66},[63,105,70],{"class":69},[63,107,74],{"class":73},[63,109,77],{"class":73},[63,111,112],{"class":73}," pm2@latest\n",[63,114,115,117],{"class":65,"line":83},[63,116,86],{"class":69},[63,118,119],{"class":73}," update\n",[10,121,123],{"id":122},"_2-starting-apps","2. Starting apps",[54,125,127],{"className":56,"code":126,"language":58,"meta":59,"style":59},"pm2 start app.js                       # the simplest form\npm2 start app.js --name api            # give it a meaningful name\npm2 start app.js --watch               # restart on file changes (for development)\npm2 start app.js --max-memory-restart 300M   # restart when memory limit is exceeded\npm2 start app.js --cron-restart=\"0 3 * * *\"  # restart every night at 03:00\npm2 start app.js --node-args=\"--max-old-space-size=4096\"\npm2 start app.js -- --port 8080        # everything after \"--\" is passed to the app\n",[29,128,129,143,160,175,193,217,237],{"__ignoreMap":59},[63,130,131,133,136,139],{"class":65,"line":66},[63,132,86],{"class":69},[63,134,135],{"class":73}," start",[63,137,138],{"class":73}," app.js",[63,140,142],{"class":141},"sHwdD","                       # the simplest form\n",[63,144,145,147,149,151,154,157],{"class":65,"line":83},[63,146,86],{"class":69},[63,148,135],{"class":73},[63,150,138],{"class":73},[63,152,153],{"class":73}," --name",[63,155,156],{"class":73}," api",[63,158,159],{"class":141},"            # give it a meaningful name\n",[63,161,163,165,167,169,172],{"class":65,"line":162},3,[63,164,86],{"class":69},[63,166,135],{"class":73},[63,168,138],{"class":73},[63,170,171],{"class":73}," --watch",[63,173,174],{"class":141},"               # restart on file changes (for development)\n",[63,176,178,180,182,184,187,190],{"class":65,"line":177},4,[63,179,86],{"class":69},[63,181,135],{"class":73},[63,183,138],{"class":73},[63,185,186],{"class":73}," --max-memory-restart",[63,188,189],{"class":73}," 300M",[63,191,192],{"class":141},"   # restart when memory limit is exceeded\n",[63,194,196,198,200,202,205,209,212,214],{"class":65,"line":195},5,[63,197,86],{"class":69},[63,199,135],{"class":73},[63,201,138],{"class":73},[63,203,204],{"class":73}," --cron-restart=",[63,206,208],{"class":207},"sMK4o","\"",[63,210,211],{"class":73},"0 3 * * *",[63,213,208],{"class":207},[63,215,216],{"class":141},"  # restart every night at 03:00\n",[63,218,220,222,224,226,229,231,234],{"class":65,"line":219},6,[63,221,86],{"class":69},[63,223,135],{"class":73},[63,225,138],{"class":73},[63,227,228],{"class":73}," --node-args=",[63,230,208],{"class":207},[63,232,233],{"class":73},"--max-old-space-size=4096",[63,235,236],{"class":207},"\"\n",[63,238,240,242,244,246,249,252,256],{"class":65,"line":239},7,[63,241,86],{"class":69},[63,243,135],{"class":73},[63,245,138],{"class":73},[63,247,248],{"class":73}," --",[63,250,251],{"class":73}," --port",[63,253,255],{"class":254},"sbssI"," 8080",[63,257,258],{"class":141},"        # everything after \"--\" is passed to the app\n",[15,260,261],{},"You can also run an npm script, another language or an arbitrary command:",[54,263,265],{"className":56,"code":264,"language":58,"meta":59,"style":59},"pm2 start npm --name web -- start          # runs \"npm start\"\npm2 start \"npm run start\" --name web       # same thing, command in quotes\npm2 start worker.py --interpreter python3  # Python script\npm2 start backup.sh --no-autorestart       # run once and exit\n",[29,266,267,288,309,327],{"__ignoreMap":59},[63,268,269,271,273,276,278,281,283,285],{"class":65,"line":66},[63,270,86],{"class":69},[63,272,135],{"class":73},[63,274,275],{"class":73}," npm",[63,277,153],{"class":73},[63,279,280],{"class":73}," web",[63,282,248],{"class":73},[63,284,135],{"class":73},[63,286,287],{"class":141},"          # runs \"npm start\"\n",[63,289,290,292,294,297,300,302,304,306],{"class":65,"line":83},[63,291,86],{"class":69},[63,293,135],{"class":73},[63,295,296],{"class":207}," \"",[63,298,299],{"class":73},"npm run start",[63,301,208],{"class":207},[63,303,153],{"class":73},[63,305,280],{"class":73},[63,307,308],{"class":141},"       # same thing, command in quotes\n",[63,310,311,313,315,318,321,324],{"class":65,"line":162},[63,312,86],{"class":69},[63,314,135],{"class":73},[63,316,317],{"class":73}," worker.py",[63,319,320],{"class":73}," --interpreter",[63,322,323],{"class":73}," python3",[63,325,326],{"class":141},"  # Python script\n",[63,328,329,331,333,336,339],{"class":65,"line":177},[63,330,86],{"class":69},[63,332,135],{"class":73},[63,334,335],{"class":73}," backup.sh",[63,337,338],{"class":73}," --no-autorestart",[63,340,341],{"class":141},"       # run once and exit\n",[10,343,345],{"id":344},"_3-listing-and-monitoring","3. Listing and monitoring",[54,347,349],{"className":56,"code":348,"language":58,"meta":59,"style":59},"pm2 list               # all processes (aliases: pm2 ls, pm2 status)\npm2 show api           # single-process details: log paths, restart count, env, uptime\npm2 monit              # live CPU\u002Fmemory and log dashboard in the terminal\npm2 jlist              # the list as JSON (for scripts)\n",[29,350,351,361,373,383],{"__ignoreMap":59},[63,352,353,355,358],{"class":65,"line":66},[63,354,86],{"class":69},[63,356,357],{"class":73}," list",[63,359,360],{"class":141},"               # all processes (aliases: pm2 ls, pm2 status)\n",[63,362,363,365,368,370],{"class":65,"line":83},[63,364,86],{"class":69},[63,366,367],{"class":73}," show",[63,369,156],{"class":73},[63,371,372],{"class":141},"           # single-process details: log paths, restart count, env, uptime\n",[63,374,375,377,380],{"class":65,"line":162},[63,376,86],{"class":69},[63,378,379],{"class":73}," monit",[63,381,382],{"class":141},"              # live CPU\u002Fmemory and log dashboard in the terminal\n",[63,384,385,387,390],{"class":65,"line":177},[63,386,86],{"class":69},[63,388,389],{"class":73}," jlist",[63,391,392],{"class":141},"              # the list as JSON (for scripts)\n",[15,394,395,396,399,400,402],{},"The ",[34,397,398],{},"↺"," column in ",[29,401,40],{}," shows the restart count. If it keeps growing, the app is crashing and being restarted; check the logs for the cause.",[10,404,406],{"id":405},"_4-stopping-restarting-deleting","4. Stopping, restarting, deleting",[54,408,410],{"className":56,"code":409,"language":58,"meta":59,"style":59},"pm2 stop api           # stop (stays in the list)\npm2 restart api        # stop + start\npm2 reload api         # zero-downtime reload (in cluster mode)\npm2 delete api         # stop and remove from the list\n\npm2 restart all\npm2 stop all\npm2 delete all\n",[29,411,412,424,436,448,460,466,475,483],{"__ignoreMap":59},[63,413,414,416,419,421],{"class":65,"line":66},[63,415,86],{"class":69},[63,417,418],{"class":73}," stop",[63,420,156],{"class":73},[63,422,423],{"class":141},"           # stop (stays in the list)\n",[63,425,426,428,431,433],{"class":65,"line":83},[63,427,86],{"class":69},[63,429,430],{"class":73}," restart",[63,432,156],{"class":73},[63,434,435],{"class":141},"        # stop + start\n",[63,437,438,440,443,445],{"class":65,"line":162},[63,439,86],{"class":69},[63,441,442],{"class":73}," reload",[63,444,156],{"class":73},[63,446,447],{"class":141},"         # zero-downtime reload (in cluster mode)\n",[63,449,450,452,455,457],{"class":65,"line":177},[63,451,86],{"class":69},[63,453,454],{"class":73}," delete",[63,456,156],{"class":73},[63,458,459],{"class":141},"         # stop and remove from the list\n",[63,461,462],{"class":65,"line":195},[63,463,465],{"emptyLinePlaceholder":464},true,"\n",[63,467,468,470,472],{"class":65,"line":219},[63,469,86],{"class":69},[63,471,430],{"class":73},[63,473,474],{"class":73}," all\n",[63,476,477,479,481],{"class":65,"line":239},[63,478,86],{"class":69},[63,480,418],{"class":73},[63,482,474],{"class":73},[63,484,486,488,490],{"class":65,"line":485},8,[63,487,86],{"class":69},[63,489,454],{"class":73},[63,491,474],{"class":73},[493,494,495,511],"table",{},[496,497,498],"thead",{},[499,500,501,505,508],"tr",{},[502,503,504],"th",{},"Command",[502,506,507],{},"What it does",[502,509,510],{},"When",[512,513,514,528,541,554],"tbody",{},[499,515,516,522,525],{},[517,518,519],"td",{},[29,520,521],{},"restart",[517,523,524],{},"Kills and restarts the process, with a brief downtime",[517,526,527],{},"Fork mode, config changes",[499,529,530,535,538],{},[517,531,532],{},[29,533,534],{},"reload",[517,536,537],{},"Replaces instances one by one, at least one stays up",[517,539,540],{},"After a deploy in cluster mode",[499,542,543,548,551],{},[517,544,545],{},[29,546,547],{},"stop",[517,549,550],{},"Stops the process, keeps its settings in the list",[517,552,553],{},"Shutting it down temporarily",[499,555,556,561,564],{},[517,557,558],{},[29,559,560],{},"delete",[517,562,563],{},"Stops the process and removes it from the list",[517,565,566],{},"Removing the app",[10,568,570],{"id":569},"_5-logs","5. Logs",[15,572,573,574,577,578,581,582,585],{},"By default PM2 writes each app's ",[29,575,576],{},"stdout"," and ",[29,579,580],{},"stderr"," under ",[29,583,584],{},"~\u002F.pm2\u002Flogs\u002F",".",[54,587,589],{"className":56,"code":588,"language":58,"meta":59,"style":59},"pm2 logs               # live logs of all apps\npm2 logs api           # only api\npm2 logs api --lines 200   # last 200 lines, then live stream\npm2 logs api --err     # error output only\npm2 logs --nostream    # print recent lines and exit\npm2 flush              # empty all log files\npm2 flush api          # empty only api's logs\n",[29,590,591,601,612,629,643,655,665],{"__ignoreMap":59},[63,592,593,595,598],{"class":65,"line":66},[63,594,86],{"class":69},[63,596,597],{"class":73}," logs",[63,599,600],{"class":141},"               # live logs of all apps\n",[63,602,603,605,607,609],{"class":65,"line":83},[63,604,86],{"class":69},[63,606,597],{"class":73},[63,608,156],{"class":73},[63,610,611],{"class":141},"           # only api\n",[63,613,614,616,618,620,623,626],{"class":65,"line":162},[63,615,86],{"class":69},[63,617,597],{"class":73},[63,619,156],{"class":73},[63,621,622],{"class":73}," --lines",[63,624,625],{"class":254}," 200",[63,627,628],{"class":141},"   # last 200 lines, then live stream\n",[63,630,631,633,635,637,640],{"class":65,"line":177},[63,632,86],{"class":69},[63,634,597],{"class":73},[63,636,156],{"class":73},[63,638,639],{"class":73}," --err",[63,641,642],{"class":141},"     # error output only\n",[63,644,645,647,649,652],{"class":65,"line":195},[63,646,86],{"class":69},[63,648,597],{"class":73},[63,650,651],{"class":73}," --nostream",[63,653,654],{"class":141},"    # print recent lines and exit\n",[63,656,657,659,662],{"class":65,"line":219},[63,658,86],{"class":69},[63,660,661],{"class":73}," flush",[63,663,664],{"class":141},"              # empty all log files\n",[63,666,667,669,671,673],{"class":65,"line":239},[63,668,86],{"class":69},[63,670,661],{"class":73},[63,672,156],{"class":73},[63,674,675],{"class":141},"          # empty only api's logs\n",[15,677,678,679,682],{},"Logs can fill up the disk over time; the ",[29,680,681],{},"pm2-logrotate"," module rotates files by size and deletes old ones:",[54,684,686],{"className":56,"code":685,"language":58,"meta":59,"style":59},"pm2 install pm2-logrotate\npm2 set pm2-logrotate:max_size 10M     # rotate when a file reaches 10 MB\npm2 set pm2-logrotate:retain 7         # keep the last 7 files\npm2 set pm2-logrotate:compress true    # gzip old files\n",[29,687,688,697,713,728],{"__ignoreMap":59},[63,689,690,692,694],{"class":65,"line":66},[63,691,86],{"class":69},[63,693,74],{"class":73},[63,695,696],{"class":73}," pm2-logrotate\n",[63,698,699,701,704,707,710],{"class":65,"line":83},[63,700,86],{"class":69},[63,702,703],{"class":73}," set",[63,705,706],{"class":73}," pm2-logrotate:max_size",[63,708,709],{"class":73}," 10M",[63,711,712],{"class":141},"     # rotate when a file reaches 10 MB\n",[63,714,715,717,719,722,725],{"class":65,"line":162},[63,716,86],{"class":69},[63,718,703],{"class":73},[63,720,721],{"class":73}," pm2-logrotate:retain",[63,723,724],{"class":254}," 7",[63,726,727],{"class":141},"         # keep the last 7 files\n",[63,729,730,732,734,737,740],{"class":65,"line":177},[63,731,86],{"class":69},[63,733,703],{"class":73},[63,735,736],{"class":73}," pm2-logrotate:compress",[63,738,739],{"class":207}," true",[63,741,742],{"class":141},"    # gzip old files\n",[10,744,746],{"id":745},"_6-cluster-mode-and-scaling","6. Cluster mode and scaling",[15,748,749],{},"Node.js runs on a single core. Cluster mode runs multiple copies of your app on the same port and spreads the load across cores — no code changes needed.",[54,751,753],{"className":56,"code":752,"language":58,"meta":59,"style":59},"pm2 start app.js -i max --name api     # one instance per CPU core\npm2 start app.js -i 4 --name api       # 4 instances\npm2 scale api 2                        # set the instance count to 2\npm2 scale api +2                       # add 2 more instances\npm2 reload api                         # reload with zero downtime\n",[29,754,755,776,796,811,825],{"__ignoreMap":59},[63,756,757,759,761,763,766,769,771,773],{"class":65,"line":66},[63,758,86],{"class":69},[63,760,135],{"class":73},[63,762,138],{"class":73},[63,764,765],{"class":73}," -i",[63,767,768],{"class":73}," max",[63,770,153],{"class":73},[63,772,156],{"class":73},[63,774,775],{"class":141},"     # one instance per CPU core\n",[63,777,778,780,782,784,786,789,791,793],{"class":65,"line":83},[63,779,86],{"class":69},[63,781,135],{"class":73},[63,783,138],{"class":73},[63,785,765],{"class":73},[63,787,788],{"class":254}," 4",[63,790,153],{"class":73},[63,792,156],{"class":73},[63,794,795],{"class":141},"       # 4 instances\n",[63,797,798,800,803,805,808],{"class":65,"line":162},[63,799,86],{"class":69},[63,801,802],{"class":73}," scale",[63,804,156],{"class":73},[63,806,807],{"class":254}," 2",[63,809,810],{"class":141},"                        # set the instance count to 2\n",[63,812,813,815,817,819,822],{"class":65,"line":177},[63,814,86],{"class":69},[63,816,802],{"class":73},[63,818,156],{"class":73},[63,820,821],{"class":73}," +2",[63,823,824],{"class":141},"                       # add 2 more instances\n",[63,826,827,829,831,833],{"class":65,"line":195},[63,828,86],{"class":69},[63,830,442],{"class":73},[63,832,156],{"class":73},[63,834,835],{"class":141},"                         # reload with zero downtime\n",[837,838,839],"blockquote",{},[15,840,841,842,845],{},"Cluster mode requires your app to be ",[34,843,844],{},"stateless",": keep sessions, caches and similar data in Redis or a database, not in memory.",[10,847,849],{"id":848},"_7-the-ecosystem-file","7. The ecosystem file",[15,851,852],{},"As command-line options pile up, it's cleaner to put them all in a config file. To generate a sample file:",[54,854,856],{"className":56,"code":855,"language":58,"meta":59,"style":59},"pm2 init simple        # creates ecosystem.config.js\n",[29,857,858],{"__ignoreMap":59},[63,859,860,862,865,868],{"class":65,"line":66},[63,861,86],{"class":69},[63,863,864],{"class":73}," init",[63,866,867],{"class":73}," simple",[63,869,870],{"class":141},"        # creates ecosystem.config.js\n",[54,872,876],{"className":873,"code":874,"language":875,"meta":59,"style":59},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F ecosystem.config.js\nmodule.exports = {\n  apps: [\n    {\n      name: 'api',\n      script: '.\u002Fdist\u002Fserver.js',\n      instances: 'max',\n      exec_mode: 'cluster',\n      max_memory_restart: '300M',\n      env: {\n        NODE_ENV: 'development',\n        PORT: 3000,\n      },\n      env_production: {\n        NODE_ENV: 'production',\n        PORT: 8080,\n      },\n    },\n    {\n      name: 'worker',\n      script: '.\u002Fdist\u002Fworker.js',\n    },\n  ],\n};\n","js",[29,877,878,883,894,907,912,930,946,962,978,995,1005,1022,1035,1041,1051,1067,1078,1083,1089,1094,1110,1126,1131,1139],{"__ignoreMap":59},[63,879,880],{"class":65,"line":66},[63,881,882],{"class":141},"\u002F\u002F ecosystem.config.js\n",[63,884,885,888,891],{"class":65,"line":83},[63,886,887],{"class":207},"module.exports",[63,889,890],{"class":207}," =",[63,892,893],{"class":207}," {\n",[63,895,896,900,903],{"class":65,"line":162},[63,897,899],{"class":898},"swJcz","  apps",[63,901,902],{"class":207},":",[63,904,906],{"class":905},"sTEyZ"," [\n",[63,908,909],{"class":65,"line":177},[63,910,911],{"class":207},"    {\n",[63,913,914,917,919,922,924,927],{"class":65,"line":195},[63,915,916],{"class":898},"      name",[63,918,902],{"class":207},[63,920,921],{"class":207}," '",[63,923,31],{"class":73},[63,925,926],{"class":207},"'",[63,928,929],{"class":207},",\n",[63,931,932,935,937,939,942,944],{"class":65,"line":219},[63,933,934],{"class":898},"      script",[63,936,902],{"class":207},[63,938,921],{"class":207},[63,940,941],{"class":73},".\u002Fdist\u002Fserver.js",[63,943,926],{"class":207},[63,945,929],{"class":207},[63,947,948,951,953,955,958,960],{"class":65,"line":239},[63,949,950],{"class":898},"      instances",[63,952,902],{"class":207},[63,954,921],{"class":207},[63,956,957],{"class":73},"max",[63,959,926],{"class":207},[63,961,929],{"class":207},[63,963,964,967,969,971,974,976],{"class":65,"line":485},[63,965,966],{"class":898},"      exec_mode",[63,968,902],{"class":207},[63,970,921],{"class":207},[63,972,973],{"class":73},"cluster",[63,975,926],{"class":207},[63,977,929],{"class":207},[63,979,981,984,986,988,991,993],{"class":65,"line":980},9,[63,982,983],{"class":898},"      max_memory_restart",[63,985,902],{"class":207},[63,987,921],{"class":207},[63,989,990],{"class":73},"300M",[63,992,926],{"class":207},[63,994,929],{"class":207},[63,996,998,1001,1003],{"class":65,"line":997},10,[63,999,1000],{"class":898},"      env",[63,1002,902],{"class":207},[63,1004,893],{"class":207},[63,1006,1008,1011,1013,1015,1018,1020],{"class":65,"line":1007},11,[63,1009,1010],{"class":898},"        NODE_ENV",[63,1012,902],{"class":207},[63,1014,921],{"class":207},[63,1016,1017],{"class":73},"development",[63,1019,926],{"class":207},[63,1021,929],{"class":207},[63,1023,1025,1028,1030,1033],{"class":65,"line":1024},12,[63,1026,1027],{"class":898},"        PORT",[63,1029,902],{"class":207},[63,1031,1032],{"class":254}," 3000",[63,1034,929],{"class":207},[63,1036,1038],{"class":65,"line":1037},13,[63,1039,1040],{"class":207},"      },\n",[63,1042,1044,1047,1049],{"class":65,"line":1043},14,[63,1045,1046],{"class":898},"      env_production",[63,1048,902],{"class":207},[63,1050,893],{"class":207},[63,1052,1054,1056,1058,1060,1063,1065],{"class":65,"line":1053},15,[63,1055,1010],{"class":898},[63,1057,902],{"class":207},[63,1059,921],{"class":207},[63,1061,1062],{"class":73},"production",[63,1064,926],{"class":207},[63,1066,929],{"class":207},[63,1068,1070,1072,1074,1076],{"class":65,"line":1069},16,[63,1071,1027],{"class":898},[63,1073,902],{"class":207},[63,1075,255],{"class":254},[63,1077,929],{"class":207},[63,1079,1081],{"class":65,"line":1080},17,[63,1082,1040],{"class":207},[63,1084,1086],{"class":65,"line":1085},18,[63,1087,1088],{"class":207},"    },\n",[63,1090,1092],{"class":65,"line":1091},19,[63,1093,911],{"class":207},[63,1095,1097,1099,1101,1103,1106,1108],{"class":65,"line":1096},20,[63,1098,916],{"class":898},[63,1100,902],{"class":207},[63,1102,921],{"class":207},[63,1104,1105],{"class":73},"worker",[63,1107,926],{"class":207},[63,1109,929],{"class":207},[63,1111,1113,1115,1117,1119,1122,1124],{"class":65,"line":1112},21,[63,1114,934],{"class":898},[63,1116,902],{"class":207},[63,1118,921],{"class":207},[63,1120,1121],{"class":73},".\u002Fdist\u002Fworker.js",[63,1123,926],{"class":207},[63,1125,929],{"class":207},[63,1127,1129],{"class":65,"line":1128},22,[63,1130,1088],{"class":207},[63,1132,1134,1137],{"class":65,"line":1133},23,[63,1135,1136],{"class":905},"  ]",[63,1138,929],{"class":207},[63,1140,1142],{"class":65,"line":1141},24,[63,1143,1144],{"class":207},"};\n",[54,1146,1148],{"className":56,"code":1147,"language":58,"meta":59,"style":59},"pm2 start ecosystem.config.js                      # start all apps (env)\npm2 start ecosystem.config.js --env production     # with env_production variables\npm2 start ecosystem.config.js --only api           # only api\npm2 reload ecosystem.config.js --env production    # zero-downtime reload after a deploy\n",[29,1149,1150,1162,1179,1194],{"__ignoreMap":59},[63,1151,1152,1154,1156,1159],{"class":65,"line":66},[63,1153,86],{"class":69},[63,1155,135],{"class":73},[63,1157,1158],{"class":73}," ecosystem.config.js",[63,1160,1161],{"class":141},"                      # start all apps (env)\n",[63,1163,1164,1166,1168,1170,1173,1176],{"class":65,"line":83},[63,1165,86],{"class":69},[63,1167,135],{"class":73},[63,1169,1158],{"class":73},[63,1171,1172],{"class":73}," --env",[63,1174,1175],{"class":73}," production",[63,1177,1178],{"class":141},"     # with env_production variables\n",[63,1180,1181,1183,1185,1187,1190,1192],{"class":65,"line":162},[63,1182,86],{"class":69},[63,1184,135],{"class":73},[63,1186,1158],{"class":73},[63,1188,1189],{"class":73}," --only",[63,1191,156],{"class":73},[63,1193,611],{"class":141},[63,1195,1196,1198,1200,1202,1204,1206],{"class":65,"line":177},[63,1197,86],{"class":69},[63,1199,442],{"class":73},[63,1201,1158],{"class":73},[63,1203,1172],{"class":73},[63,1205,1175],{"class":73},[63,1207,1208],{"class":141},"    # zero-downtime reload after a deploy\n",[15,1210,1211],{},"Commit this file to Git with the project, and how the app is run gets versioned along with the code.",[10,1213,1215],{"id":1214},"_8-environment-variables","8. Environment variables",[15,1217,1218,1219,1221,1222,902],{},"PM2 stores the environment variables from when the app was first started. After changing a variable, a plain ",[29,1220,521],{}," isn't enough; add ",[29,1223,1224],{},"--update-env",[54,1226,1228],{"className":56,"code":1227,"language":58,"meta":59,"style":59},"NODE_ENV=production pm2 restart api --update-env\npm2 env 0              # show the env of the process with id 0\n",[29,1229,1230,1250],{"__ignoreMap":59},[63,1231,1232,1235,1238,1240,1243,1245,1247],{"class":65,"line":66},[63,1233,1234],{"class":905},"NODE_ENV",[63,1236,1237],{"class":207},"=",[63,1239,1062],{"class":73},[63,1241,1242],{"class":69}," pm2",[63,1244,430],{"class":73},[63,1246,156],{"class":73},[63,1248,1249],{"class":73}," --update-env\n",[63,1251,1252,1254,1257,1260],{"class":65,"line":83},[63,1253,86],{"class":69},[63,1255,1256],{"class":73}," env",[63,1258,1259],{"class":254}," 0",[63,1261,1262],{"class":141},"              # show the env of the process with id 0\n",[10,1264,1266],{"id":1265},"_9-starting-on-boot","9. Starting on boot",[15,1268,1269],{},"Two steps are needed for your apps to come back after a server reboot:",[54,1271,1273],{"className":56,"code":1272,"language":58,"meta":59,"style":59},"pm2 startup            # detects the init system (systemd etc.) and prints a sudo command to run\n# run the printed \"sudo env PATH=... pm2 startup systemd -u user --hp \u002Fhome\u002Fuser\" command\n\npm2 save               # save the current process list to ~\u002F.pm2\u002Fdump.pm2\n",[29,1274,1275,1285,1290,1294],{"__ignoreMap":59},[63,1276,1277,1279,1282],{"class":65,"line":66},[63,1278,86],{"class":69},[63,1280,1281],{"class":73}," startup",[63,1283,1284],{"class":141},"            # detects the init system (systemd etc.) and prints a sudo command to run\n",[63,1286,1287],{"class":65,"line":83},[63,1288,1289],{"class":141},"# run the printed \"sudo env PATH=... pm2 startup systemd -u user --hp \u002Fhome\u002Fuser\" command\n",[63,1291,1292],{"class":65,"line":162},[63,1293,465],{"emptyLinePlaceholder":464},[63,1295,1296,1298,1301],{"class":65,"line":177},[63,1297,86],{"class":69},[63,1299,1300],{"class":73}," save",[63,1302,1303],{"class":141},"               # save the current process list to ~\u002F.pm2\u002Fdump.pm2\n",[15,1305,1306,1307,1310],{},"On boot, PM2 restores this saved list. Don't forget to run ",[29,1308,1309],{},"pm2 save"," again after adding or removing apps.",[54,1312,1314],{"className":56,"code":1313,"language":58,"meta":59,"style":59},"pm2 resurrect          # restore the saved list manually\npm2 unstartup systemd  # remove the startup hook\n",[29,1315,1316,1326],{"__ignoreMap":59},[63,1317,1318,1320,1323],{"class":65,"line":66},[63,1319,86],{"class":69},[63,1321,1322],{"class":73}," resurrect",[63,1324,1325],{"class":141},"          # restore the saved list manually\n",[63,1327,1328,1330,1333,1336],{"class":65,"line":83},[63,1329,86],{"class":69},[63,1331,1332],{"class":73}," unstartup",[63,1334,1335],{"class":73}," systemd",[63,1337,1338],{"class":141},"  # remove the startup hook\n",[837,1340,1341],{},[15,1342,1343,1344,1347,1348,1351],{},"If you installed Node.js with nvm and switched versions, repeat ",[29,1345,1346],{},"pm2 unstartup"," + ",[29,1349,1350],{},"pm2 startup","; the startup script may still point to the old Node path.",[10,1353,1355],{"id":1354},"_10-maintenance-and-troubleshooting","10. Maintenance and troubleshooting",[54,1357,1359],{"className":56,"code":1358,"language":58,"meta":59,"style":59},"pm2 reset api          # reset metrics such as the restart counter\npm2 describe api       # same as pm2 show\npm2 ping               # is the daemon alive?\npm2 kill               # stop the daemon and all processes\n",[29,1360,1361,1373,1385,1395],{"__ignoreMap":59},[63,1362,1363,1365,1368,1370],{"class":65,"line":66},[63,1364,86],{"class":69},[63,1366,1367],{"class":73}," reset",[63,1369,156],{"class":73},[63,1371,1372],{"class":141},"          # reset metrics such as the restart counter\n",[63,1374,1375,1377,1380,1382],{"class":65,"line":83},[63,1376,86],{"class":69},[63,1378,1379],{"class":73}," describe",[63,1381,156],{"class":73},[63,1383,1384],{"class":141},"       # same as pm2 show\n",[63,1386,1387,1389,1392],{"class":65,"line":162},[63,1388,86],{"class":69},[63,1390,1391],{"class":73}," ping",[63,1393,1394],{"class":141},"               # is the daemon alive?\n",[63,1396,1397,1399,1402],{"class":65,"line":177},[63,1398,86],{"class":69},[63,1400,1401],{"class":73}," kill",[63,1403,1404],{"class":141},"               # stop the daemon and all processes\n",[15,1406,1407],{},"Common situations:",[493,1409,1410,1420],{},[496,1411,1412],{},[499,1413,1414,1417],{},[502,1415,1416],{},"Situation",[502,1418,1419],{},"Fix",[512,1421,1422,1433,1443,1456,1469],{},[499,1423,1424,1427],{},[517,1425,1426],{},"App keeps restarting (↺ growing)",[517,1428,1429,1430],{},"Find the error with ",[29,1431,1432],{},"pm2 logs api --err --lines 100",[499,1434,1435,1438],{},[517,1436,1437],{},"New env variable doesn't reach the app",[517,1439,1440],{},[29,1441,1442],{},"pm2 restart api --update-env",[499,1444,1445,1448],{},[517,1446,1447],{},"Apps are gone after a reboot",[517,1449,1450,1451,1453,1454],{},"Run the command printed by ",[29,1452,1350],{},", then ",[29,1455,1309],{},[499,1457,1458,1461],{},[517,1459,1460],{},"Disk filled up with logs",[517,1462,1463,1466,1467],{},[29,1464,1465],{},"pm2 flush"," + install ",[29,1468,681],{},[499,1470,1471,1474],{},[517,1472,1473],{},"\"In-memory PM2 is out-of-date\" warning after an upgrade",[517,1475,1476],{},[29,1477,95],{},[10,1479,1481],{"id":1480},"conclusion","Conclusion",[15,1483,1484,1485,1488,1489,1488,1492,1488,1495,1497,1498,577,1500,1503,1504,1507,1508,1514,1515,1519],{},"Most day-to-day PM2 work comes down to ",[29,1486,1487],{},"start",", ",[29,1490,1491],{},"list",[29,1493,1494],{},"logs",[29,1496,521],{},"\u002F",[29,1499,534],{},[29,1501,1502],{},"save",". When going to production, remember three things: keep your settings in an ",[34,1505,1506],{},"ecosystem file",", set up startup on boot with ",[34,1509,1510,1347,1512],{},[29,1511,1350],{},[29,1513,1309],{},", and use ",[34,1516,1517],{},[29,1518,681],{}," to keep logs from filling the disk.",[1521,1522,1523],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":59,"searchDepth":83,"depth":83,"links":1525},[1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537],{"id":12,"depth":83,"text":13},{"id":48,"depth":83,"text":49},{"id":122,"depth":83,"text":123},{"id":344,"depth":83,"text":345},{"id":405,"depth":83,"text":406},{"id":569,"depth":83,"text":570},{"id":745,"depth":83,"text":746},{"id":848,"depth":83,"text":849},{"id":1214,"depth":83,"text":1215},{"id":1265,"depth":83,"text":1266},{"id":1354,"depth":83,"text":1355},{"id":1480,"depth":83,"text":1481},"2026-10-24","The most-used commands of PM2, the process manager that keeps Node.js apps alive in production — starting, monitoring, logs, cluster mode, the ecosystem file and startup on boot.","md",{},"\u002Fen\u002Fblog\u002Ffrequently-used-pm2-commands",{"title":5,"description":1539},"en\u002Fblog\u002Ffrequently-used-pm2-commands",[86,1546,1547],"nodejs","guide","\u002Fblog\u002Ffrequently-used-pm2-commands","BW2R9tOXB88n6HxB2nuXpqIiOfrQ7e4KwGEgNPPvNLU",1792871132084]