You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Packer在Windows Server 2019上安装PostgreSQL提前终止无报错

解决Packer在Windows Server 2019上安装PostgreSQL中途终止的问题

核心原因

Packer的Windows provisioner默认只等命令的父进程退出,但PostgreSQL安装程序(不管是exe版还是Chocolatey调用的)常会启动子进程后让父进程提前退出,导致Packer误判安装完成,直接跳到下一阶段。


具体解决方案

1. 用Start-Process强制等待所有子进程(exe安装)

把安装命令封装进Start-Process,加上-Wait和-NoNewWindow参数,确保Packer等所有安装相关进程结束,同时保留日志方便排查:

# 先创建日志目录
New-Item -Path C:\temp -ItemType Directory -Force
# 执行PostgreSQL无人值守安装
Start-Process -FilePath "postgresql-12.17-1-windows-x64.exe" `
  -ArgumentList "--mode unattended --superpassword yourSecurePassword --prefix ""C:\Program Files\PostgreSQL\12"" --datadir ""C:\Program Files\PostgreSQL\12\data"" --enable-components server,commandline-tools" `
  -Wait -NoNewWindow `
  -RedirectStandardOutput "C:\temp\pg_install.log" `
  -RedirectStandardError "C:\temp\pg_install_err.log"
  • -Wait:强制等待整个安装流程结束,不是只等父进程
  • -NoNewWindow:让安装输出直接显示在Packer控制台
  • 日志参数:把安装过程的输出/错误存到本地,事后能查具体卡在哪一步

2. 给Chocolatey加强制等待参数

用Chocolatey安装时,默认逻辑可能没等子进程,加上--wait参数强制它等所有安装进程结束:

choco install postgresql12 --version 12.17.0 --yes --force --wait `
  --install-arguments="--mode unattended --superpassword yourSecurePassword"
  • --wait:关键参数,让Chocolatey不提前返回
  • --force:避免缓存的旧安装包导致异常

3. 在Packer配置里加验证步骤

修改Packer的powershell provisioner,安装后直接检查PostgreSQL服务是否存在,没装成就中断构建,避免白跑后续流程:

provisioner "powershell" {
  elevated          = true
  timeout           = "30m" # 安装可能耗时久,调大超时时间
  inline = [
    "New-Item -Path C:\\temp -ItemType Directory -Force",
    "Start-Process -FilePath 'choco' -ArgumentList 'install postgresql12 --version 12.17.0 --yes --wait --install-arguments=""--mode unattended --superpassword yourSecurePassword""' -Wait -NoNewWindow -RedirectStandardOutput C:\\temp\\choco_pg.log -RedirectStandardError C:\\temp\\choco_pg_err.log",
    # 验证服务是否存在
    "$pgService = Get-Service -Name postgresql-x64-12 -ErrorAction SilentlyContinue",
    "If (-not $pgService) { throw 'PostgreSQL安装失败,服务未创建' }"
  ]
}

4. 手动捕获进程树(极端情况用)

如果以上方法还是不行,直接写脚本捕获安装程序的所有子进程,强制等它们全部结束:

$installProcess = Start-Process -FilePath "postgresql-12.17-1-windows-x64.exe" `
  -ArgumentList "--mode unattended --superpassword yourSecurePassword" `
  -PassThru -NoNewWindow

# 循环等待主进程和所有子进程退出
do {
  $installProcess.Refresh()
  $childProcesses = Get-Process -Id $installProcess.Id -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Id | ForEach-Object { Get-Process -Id $_ -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Children }
  Start-Sleep -Seconds 5
} while ($installProcess.HasExited -eq $false -or $childProcesses.Count -gt 0)

排查技巧

  • 看日志:打开C:\temp下的安装日志,确认安装程序实际执行到哪一步停了
  • Packer调试模式:用packer build -debug启动,构建暂停时远程登机器,用tasklist看有没有PostgreSQL相关进程在跑
  • Windows事件日志:去Windows Logs > Application里找PostgreSQL的安装错误信息

内容的提问来源于stack exchange,提问作者kirkpatt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 04:00:24