- Dockerfile 改为 Node 24 运行时:Vike 产物 + Go API 二进制共用镜像 - docker-compose 双容器:web(:3000 对外 SSR) + api(:3001 内部,持 /data 卷) - entrypoint 改用 gosu 降权(Debian 基础镜像),健康检查用 node fetch - Makefile/build.ps1:build 不再打包前端,新增 serve(本地双进程)与 web-build - README 同步双服务架构、端口/环境变量、部署与开发说明
180 lines
7.1 KiB
PowerShell
180 lines
7.1 KiB
PowerShell
# Jiang13 Forum - Windows build script (replaces GNU Make)
|
||
# Usage: .\build.ps1
|
||
# .\build.ps1 -Target build-windows
|
||
|
||
param(
|
||
[ValidateSet('build', 'web-build', 'frontend', 'build-windows', 'build-linux', 'build-darwin', 'build-all', 'tidy', 'run', 'serve', 'dev', 'clean', 'docker', 'compose-up', 'compose-down', 'help')]
|
||
[string]$Target = 'build'
|
||
)
|
||
|
||
$ErrorActionPreference = 'Stop'
|
||
$AppName = 'jiang13'
|
||
$MainPkg = './cmd/jiang13'
|
||
$BuildDir = 'dist'
|
||
$DevDataDir = 'dist/data'
|
||
$Version = '1.1.8'
|
||
$RegistryImage = 'hangzhang714128/jiang13-forum'
|
||
$Ldlags = "-s -w -X main.version=$Version"
|
||
|
||
function Ensure-Dir($path) {
|
||
if (-not (Test-Path $path)) {
|
||
New-Item -ItemType Directory -Path $path | Out-Null
|
||
}
|
||
}
|
||
|
||
function Build-Frontend {
|
||
Write-Host '[frontend] npm run build (Vike: client + server)...' -ForegroundColor Cyan
|
||
Push-Location frontend
|
||
try {
|
||
if (-not (Test-Path node_modules)) {
|
||
npm install
|
||
}
|
||
npm run build
|
||
if ($LASTEXITCODE -ne 0) { throw 'frontend build failed' }
|
||
} finally {
|
||
Pop-Location
|
||
}
|
||
}
|
||
|
||
function Build-Go([string]$OutFile, [string]$GoOS = '', [string]$GoArch = '') {
|
||
Ensure-Dir $BuildDir
|
||
if ($GoOS) { $env:GOOS = $GoOS } else { Remove-Item Env:GOOS -ErrorAction SilentlyContinue }
|
||
if ($GoArch) { $env:GOARCH = $GoArch } else { Remove-Item Env:GOARCH -ErrorAction SilentlyContinue }
|
||
|
||
# 纯 Go SQLite(glebarez),交叉编译无需 C 工具链
|
||
$prevCgo = $env:CGO_ENABLED
|
||
$env:CGO_ENABLED = '0'
|
||
|
||
$isWindows = ($GoOS -eq 'windows') -or (($GoOS -eq '') -and ($env:OS -match 'Windows'))
|
||
if ($isWindows -and ($OutFile -notmatch '\.exe$')) {
|
||
$OutFile = "$OutFile.exe"
|
||
}
|
||
|
||
$outPath = Join-Path $BuildDir $OutFile
|
||
Write-Host "[go] build -> $outPath (CGO_ENABLED=0)" -ForegroundColor Cyan
|
||
try {
|
||
go build -trimpath -ldflags $Ldlags -o $outPath $MainPkg
|
||
if ($LASTEXITCODE -ne 0) { throw 'go build failed' }
|
||
Write-Host "[ok] $outPath" -ForegroundColor Green
|
||
} finally {
|
||
if ($null -eq $prevCgo) {
|
||
Remove-Item Env:CGO_ENABLED -ErrorAction SilentlyContinue
|
||
} else {
|
||
$env:CGO_ENABLED = $prevCgo
|
||
}
|
||
Remove-Item Env:GOOS -ErrorAction SilentlyContinue
|
||
Remove-Item Env:GOARCH -ErrorAction SilentlyContinue
|
||
}
|
||
}
|
||
|
||
switch ($Target) {
|
||
'help' {
|
||
Write-Host '.\build.ps1 build Go API binary (current platform)'
|
||
Write-Host '.\build.ps1 -Target web-build build frontend (Vike client + server)'
|
||
Write-Host '.\build.ps1 -Target serve production run: Node :3000 + Go API :3001'
|
||
Write-Host '.\build.ps1 -Target build-windows'
|
||
Write-Host '.\build.ps1 -Target build-linux'
|
||
Write-Host '.\build.ps1 -Target build-all'
|
||
Write-Host '.\build.ps1 -Target run Go API only (port 3000, no pages)'
|
||
Write-Host '.\build.ps1 -Target dev Vike HMR :5173 + Go API :3000 (recommended for frontend dev)'
|
||
Write-Host '.\build.ps1 -Target tidy'
|
||
Write-Host '.\build.ps1 -Target clean'
|
||
Write-Host '.\build.ps1 -Target docker build Docker image'
|
||
Write-Host '.\build.ps1 -Target compose-up docker compose up -d --build'
|
||
Write-Host '.\build.ps1 -Target compose-down docker compose down'
|
||
Write-Host ''
|
||
Write-Host 'Note: Windows "make" is often Embarcadero MAKE, not GNU Make.'
|
||
}
|
||
'web-build' { Build-Frontend }
|
||
'frontend' { Build-Frontend }
|
||
'tidy' { go mod tidy }
|
||
'clean' {
|
||
if (Test-Path $BuildDir) { Remove-Item -Recurse -Force $BuildDir }
|
||
Write-Host '[ok] cleaned dist' -ForegroundColor Green
|
||
}
|
||
'run' {
|
||
Ensure-Dir $DevDataDir
|
||
go run $MainPkg --data $DevDataDir
|
||
}
|
||
'serve' {
|
||
Build-Frontend
|
||
Build-Go -OutFile $AppName
|
||
Ensure-Dir $DevDataDir
|
||
$root = (Get-Location).Path
|
||
$goExe = Join-Path $root "$BuildDir\$AppName.exe"
|
||
Write-Host '[serve] 正在新窗口启动 Go API (:3001)...' -ForegroundColor Cyan
|
||
Start-Process powershell -ArgumentList @(
|
||
'-NoExit', '-Command',
|
||
"Set-Location '$root'; & '$goExe' --data '$DevDataDir' --port 3001"
|
||
) | Out-Null
|
||
Start-Sleep -Seconds 2
|
||
Write-Host '[serve] 启动 Node 渲染服务器 (:3000)...' -ForegroundColor Cyan
|
||
Push-Location frontend
|
||
try {
|
||
$env:PORT = '3000'
|
||
$env:GO_API_URL = 'http://127.0.0.1:3001'
|
||
npm start
|
||
} finally {
|
||
Remove-Item Env:PORT -ErrorAction SilentlyContinue
|
||
Remove-Item Env:GO_API_URL -ErrorAction SilentlyContinue
|
||
Pop-Location
|
||
}
|
||
}
|
||
'dev' {
|
||
$root = (Get-Location).Path
|
||
Ensure-Dir $DevDataDir
|
||
Write-Host ''
|
||
Write-Host '[dev] 前端开发 : http://localhost:5173 (Vike HMR)' -ForegroundColor Green
|
||
Write-Host '[dev] 后端 API : http://localhost:3000 (Go)' -ForegroundColor Green
|
||
Write-Host "[dev] 数据目录 : $DevDataDir (与 dist 二进制一致)" -ForegroundColor Green
|
||
Write-Host '[dev] 提示 : 请访问 5173 端口,Vite 会自动代理 API 到 3000' -ForegroundColor Yellow
|
||
Write-Host '[dev] 正在新窗口启动 Go 后端 (仅 API)...' -ForegroundColor Cyan
|
||
Start-Process powershell -ArgumentList @(
|
||
'-NoExit', '-Command',
|
||
"Set-Location '$root'; Write-Host '[backend] Go API on :3000' -ForegroundColor Cyan; go run $MainPkg --dev --data '$DevDataDir'"
|
||
) | Out-Null
|
||
Start-Sleep -Seconds 2
|
||
Push-Location frontend
|
||
try {
|
||
if (-not (Test-Path node_modules)) { npm install }
|
||
npm run dev
|
||
} finally {
|
||
Pop-Location
|
||
}
|
||
}
|
||
'build' {
|
||
Build-Go -OutFile $AppName
|
||
}
|
||
'build-windows' {
|
||
Build-Go -OutFile $AppName -GoOS 'windows' -GoArch 'amd64'
|
||
}
|
||
'build-linux' {
|
||
Build-Go -OutFile "$AppName-linux-amd64" -GoOS 'linux' -GoArch 'amd64'
|
||
}
|
||
'build-darwin' {
|
||
Build-Go -OutFile "$AppName-darwin-arm64" -GoOS 'darwin' -GoArch 'arm64'
|
||
}
|
||
'build-all' {
|
||
Build-Go -OutFile $AppName -GoOS 'windows' -GoArch 'amd64'
|
||
Build-Go -OutFile "$AppName-linux-amd64" -GoOS 'linux' -GoArch 'amd64'
|
||
Build-Go -OutFile "$AppName-darwin-arm64" -GoOS 'darwin' -GoArch 'arm64'
|
||
Write-Host '[ok] all platforms done' -ForegroundColor Green
|
||
}
|
||
'docker' {
|
||
Write-Host "[docker] build $RegistryImage`:$Version and latest" -ForegroundColor Cyan
|
||
docker build --build-arg "VERSION=$Version" -t "${RegistryImage}:$Version" -t "${RegistryImage}:latest" .
|
||
if ($LASTEXITCODE -ne 0) { throw 'docker build failed' }
|
||
Write-Host '[ok] docker image built' -ForegroundColor Green
|
||
}
|
||
'compose-up' {
|
||
docker compose up -d --build
|
||
if ($LASTEXITCODE -ne 0) { throw 'docker compose up failed' }
|
||
Write-Host '[ok] compose started' -ForegroundColor Green
|
||
}
|
||
'compose-down' {
|
||
docker compose down
|
||
if ($LASTEXITCODE -ne 0) { throw 'docker compose down failed' }
|
||
Write-Host '[ok] compose stopped' -ForegroundColor Green
|
||
}
|
||
}
|