我在 Windows 上使用 PM2 来启动 Nodejs 应用程序。
我希望 PM2 在 Windows 启动(引导、重新启动等)时也启动。
我尝试使用 pm2-windows-service 将 PM2 设置为 Windows 服务,但没有成功。
如何将 PM2 设置为服务?
使用 pm2-service-install 来变量 Pm2 进行服务 将以下脚本(ps1)放入源代码文件夹中
# Deploys application as an app within a PM2 service
# Run from root of Node application
param(
[string] $Pm2Home = $env:PM2_HOME,
[string] $AppStart = "app.js"
)
$ErrorActionPreference = "Stop"
function Install-Node-Modules
{
Write-Host "Running npm install"
& "npm" i
}
function Create-Pm2-Home
{
Write-Host "Attempting to create $Pm2Home and give FullControl to LOCAL SERVICE"
New-Item -ItemType Directory -Force -Path $Pm2Home
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"LOCAL SERVICE", "FullControl", "ContainerInherit, ObjectInherit",
"None", "Allow")
try {
$acl = Get-Acl -Path $Pm2Home -ErrorAction Stop
$acl.SetAccessRule($rule)
Set-Acl -Path $Pm2Home -AclObject $acl -ErrorAction Stop
Write-Host "Successfully set FullControl permissions on $Pm2Home"
} catch {
throw "$Pm2Home : Failed to set permissions. Details : $_"
}
}
function Install-Pm2-Service
{
$UserPath = $env:userprofile
Write-Host "Installing pm2"
& "npm" i "pm2@latest" "-g"
Write-Host "Installing pm2-windows-service npm module"
& "npm" i pm2-windows-service "-g"
& "npm" install "-g" npm-check-updates
& "cd" \
& "cd" $UserPath\AppData\Roaming\npm\node_modules\pm2-windows-service
& "ncu" inquirer "-u"
& "npm" install
& "pm2-service-install" "--unattended"
# Create wrapper log file, otherwise it won't start
$wrapperLogPath = "$(npm config get prefix)\node_modules\pm2-windows-service\src\daemon\pm2.wrapper.log"
if (Test-Path $wrapperLogPath) {
Write-Debug "PM2 service wrapper log file already exists"
} else {
Out-File $wrapperLogPath -Encoding utf8
}
}
function Create-Pm2-Service-Config
{
param([string] $ConfigPath, [string] $CmdPath)
$configContent = @"
{
"apps": [{
"name": "node-app",
"script": "$($CmdPath -replace "\\","\\")",
"args": [],
"cwd": "$((Split-Path $CmdPath) -replace "\\","\\")",
"merge_logs": true,
"instances": 4,
"exec_mode": "cluster_mode",
"env": {
"NODE_ENV": "development"
}
}]
}
"@
# Write out config to JSON file
Write-Host "Writing PM2 service configuration to $ConfigPath"
$configContent | Out-File $ConfigPath -Encoding utf8
}
# From http://stackoverflow.com/a/4370900/964356
function Set-ServiceAcctCreds
{
param([string] $serviceName, [string] $newAcct, [string] $newPass)
$filter = "Name='$serviceName'"
$tries = 0
while (($service -eq $null -and $tries -le 3)) {
if ($tries -ne 0) {
sleep 2
}
$service = Get-WMIObject -namespace "root\cimv2" -class Win32_Service -Filter $filter
$tries = $tries + 1
}
if ($service -eq $null) {
throw "Could not find '$serviceName' service"
}
$service.Change($null,$null,$null,$null,$null,$null,$newAcct,$newPass)
$service.StopService()
while ($service.Started) {
sleep 2
$service = Get-WMIObject -namespace "root\cimv2" -class Win32_Service -Filter $filter
}
$service.StartService()
}
function Change-Pm2-Service-Account
{
Write-Host "Changing PM2 to run as LOCAL SERVICE"
Set-ServiceAcctCreds -serviceName "pm2.exe" -newAcct "NT AUTHORITY\LocalService" -newPass ""
}
$env:PM2_HOME = $Pm2Home
$env:PM2_SERVICE_SCRIPTS = "$Pm2Home\ecosystem.json"
[Environment]::SetEnvironmentVariable("PM2_HOME", $env:PM2_HOME, "Machine")
[Environment]::SetEnvironmentVariable("PM2_SERVICE_SCRIPTS", $env:PM2_SERVICE_SCRIPTS, "Machine")
& Install-Node-Modules
& Create-Pm2-Home
& Create-Pm2-Service-Config -ConfigPath $env:PM2_SERVICE_SCRIPTS -CmdPath $AppStart
& Install-Pm2-Service
& Change-Pm2-Service-Account
执行以下命令。
.\install.ps1 -Pm2Home "C:\Users\Admin\.pm2" -AppStart "C:\SourceCode\app.js"
In it:
C:\Users\Admin\.pm2 : .pm2 path
C:\SourceCode\app.js : App.js path
在提示中输入以下内容。
? Perform environment setup (recommended)? Yes
? Set PM2_HOME? Yes
? PM2_HOME value (this path should be accessible to the service user and should not contain any “user-context” variables [e.g. %APPDATA%]): c:\etc\.pm2\
? Set PM2_SERVICE_SCRIPTS (the list of start-up scripts for pm2)? No
? Set PM2_SERVICE_PM2_DIR (the location of the global pm2 to use with the service)
? [recommended] Yes ? Specify the directory containing the pm2 version to be used by the service C:\USERS\<USER>\APPDATA\ROAMING\NPM\node_modules\pm2\index.js