Release: weekly deploy

This commit is contained in:
Danila Khodjaef
2026-07-09 16:03:48 +03:00
parent 0ceb1c1c8c
commit 62096e8210
16 changed files with 169 additions and 38 deletions
View File
@@ -22,9 +22,6 @@
"stageAll": true
},
"schemaChanged": false,
"release": {
"imageTag": "latest"
},
"backupFile": "",
"smb": {
"host": "192.168.10.122",
-1
View File
@@ -11,7 +11,6 @@ DB_NAME=gallery_prod
PORT=5173
HOST=0.0.0.0
APP_ENV=prod
IMAGE_TAG=latest
PUBLIC_URL=https://gallery.mysuperlab.netcraze.pro
TRUST_PROXY=true
IMAGE_DIR=/app/data/images
+8
View File
@@ -23,10 +23,18 @@ COPY client ./client
RUN npm run build --prefix client
FROM node:20-alpine AS runner
ARG APP_VERSION=0.0.0
ARG GIT_SHA=
ARG IMAGE_TAG=latest
ARG BUILD_TIME=
ENV NODE_ENV=production
ENV PORT=5173
ENV HOST=0.0.0.0
ENV IMAGE_DIR=/app/data/images
ENV APP_VERSION=$APP_VERSION
ENV GIT_SHA=$GIT_SHA
ENV IMAGE_TAG=$IMAGE_TAG
ENV BUILD_TIME=$BUILD_TIME
RUN addgroup --system --gid 1001 nodejs \
&& adduser --system --uid 1001 --ingroup nodejs gallery
+38 -5
View File
@@ -1,15 +1,17 @@
# Build and push the production web image to Gitea over LAN (fast path).
param(
[string]$Tag = "latest",
[string]$Tag = '',
[switch]$SkipHosts,
[switch]$SkipBuild
)
$ErrorActionPreference = "Stop"
. (Join-Path $PSScriptRoot "..\scripts\lib\Deploy-CliResult.ps1")
. (Join-Path $PSScriptRoot "..\scripts\lib\Build-ReleaseTag.ps1")
$Registry = "gitea.mysuperlab.netcraze.pro"
$Image = "$Registry/danilka/gallery-web"
$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path
function Test-DockerRunning {
$prevEap = $ErrorActionPreference
@@ -27,10 +29,24 @@ if (-not (Test-DockerRunning)) {
exit 1
}
$meta = Get-BuildMetadata -RepoRoot $RepoRoot
$releaseTag = if ($Tag -and $Tag.Trim()) { $Tag.Trim() } else { $meta.ReleaseTag }
$meta.ReleaseTag = $releaseTag
Write-Host "Release tag: $releaseTag"
Write-Host "Build metadata: app_version=$($meta.AppVersion), git_sha=$($meta.GitSha), built_at=$($meta.BuildTimeUtc)"
if (-not $SkipBuild) {
Write-Host ""
Write-Host "Building ${Image}:${Tag} ..."
docker build -f infra/docker/Dockerfile -t "${Image}:${Tag}" .
Write-Host "Building ${Image}:$releaseTag and ${Image}:latest ..."
docker build -f infra/docker/Dockerfile `
--build-arg "APP_VERSION=$($meta.AppVersion)" `
--build-arg "GIT_SHA=$($meta.GitSha)" `
--build-arg "IMAGE_TAG=$releaseTag" `
--build-arg "BUILD_TIME=$($meta.BuildTimeUtc)" `
-t "${Image}:$releaseTag" `
-t "${Image}:latest" `
$RepoRoot
if ($LASTEXITCODE -ne 0) {
Write-DeployCliResult -Script 'build-push-lan' -Success $false -Summary "Docker build failed with exit code $LASTEXITCODE"
exit $LASTEXITCODE
@@ -41,11 +57,28 @@ if (-not $SkipBuild) {
}
Write-Host ""
& "$PSScriptRoot/push-lan.ps1" -Tag $Tag -SkipHosts:$SkipHosts
if ($SkipBuild) {
$pushTags = @('latest')
if ($Tag -and $Tag.Trim()) {
$pushTags = @($Tag.Trim(), 'latest') | Select-Object -Unique
}
} else {
$pushTags = @($releaseTag, 'latest') | Select-Object -Unique
}
& "$PSScriptRoot/push-lan.ps1" -Tags $pushTags -SkipHosts:$SkipHosts
if ($LASTEXITCODE -ne 0) {
Write-DeployCliResult -Script 'build-push-lan' -Success $false -Summary "Docker push failed with exit code $LASTEXITCODE"
exit $LASTEXITCODE
}
Write-DeployCliResult -Script 'build-push-lan' -Success $true -Summary 'Docker image built and pushed to Gitea.' -Details @("Image: ${Image}:${Tag}")
$manifestPath = Write-LastDockerRelease -RepoRoot $RepoRoot -Metadata $meta -Image "${Image}:$releaseTag"
Write-DeployCliResult -Script 'build-push-lan' -Success $true -Summary 'Docker image built and pushed to Gitea.' -Details @(
"Release tag: $releaseTag",
"Also pushed as: latest",
"Git commit: $($meta.GitSha)",
"Built at: $($meta.BuildTimeUtc)",
"Manifest: $manifestPath",
"TrueNAS: restart gallery-web (pull_policy: always uses latest)."
)
exit 0
+1 -1
View File
@@ -6,7 +6,7 @@ services:
build:
context: ../..
dockerfile: infra/docker/Dockerfile
image: gitea.mysuperlab.netcraze.pro/danilka/gallery-web:${IMAGE_TAG:-latest}
image: gitea.mysuperlab.netcraze.pro/danilka/gallery-web:latest
container_name: gallery-web
restart: unless-stopped
ports:
+1 -2
View File
@@ -10,7 +10,7 @@
# See infra/docker/DEPLOY-truenas.md and Documentation/environments.md
services:
web:
image: gitea.mysuperlab.netcraze.pro/danilka/gallery-web:${IMAGE_TAG:-latest}
image: gitea.mysuperlab.netcraze.pro/danilka/gallery-web:latest
container_name: gallery-web
restart: unless-stopped
pull_policy: always
@@ -19,7 +19,6 @@ services:
environment:
NODE_ENV: production
APP_ENV: "prod"
IMAGE_TAG: "${IMAGE_TAG:-latest}"
PORT: "5173"
HOST: "0.0.0.0"
DB_HOST: "192.168.10.122"
+7 -5
View File
@@ -1,6 +1,6 @@
# Push Docker image to Gitea over LAN (avoids KeenDNS hairpin slow upload).
param(
[string]$Tag = "latest",
[string[]]$Tags = @('latest'),
[switch]$SkipHosts
)
@@ -55,10 +55,12 @@ if (-not $SkipHosts) {
$after = Get-GiteaDnsAddress
Write-Host "After override, resolves to: $after"
Write-Host ""
Write-Host "Pushing ${Image}:${Tag} ..."
docker push "${Image}:${Tag}"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
foreach ($tag in ($Tags | Select-Object -Unique)) {
Write-Host ""
Write-Host "Pushing ${Image}:$tag ..."
docker push "${Image}:$tag"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
Write-Host ""
Write-Host "Done. Remove hosts entry ($HostsMarker) when finished if you no longer need LAN override." -ForegroundColor Cyan
+1 -3
View File
@@ -564,9 +564,7 @@ if (Get-StepEnabled $steps 'syncImages') {
if (Get-StepEnabled $steps 'dockerPublish') {
$ok = Invoke-Step 'dockerPublish' {
$tag = if ($cfg.release.imageTag) { $cfg.release.imageTag } else { 'latest' }
Write-Host "Docker release tag: $tag"
$code = Invoke-Npm 'prod:docker:publish' @('-Tag', $tag)
$code = Invoke-Npm 'prod:docker:publish'
return $code
}
if (-not $ok) { Write-ReleaseBanner -Success $false -FailedAt $FailedStep; exit 1 }
+58
View File
@@ -0,0 +1,58 @@
function Get-BuildMetadata {
param([string]$RepoRoot)
$gitSha = ''
$appVersion = '0.0.0'
try {
Push-Location $RepoRoot
$gitSha = (git rev-parse --short HEAD 2>$null).Trim()
$appVersion = (node -p "require('./package.json').version" 2>$null).Trim()
} finally {
Pop-Location
}
if (-not $gitSha) { $gitSha = 'unknown' }
if (-not $appVersion) { $appVersion = '0.0.0' }
$buildTime = Get-Date
$buildTimeUtc = $buildTime.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss'Z'")
return @{
GitSha = $gitSha
AppVersion = $appVersion
BuildTimeUtc = $buildTimeUtc
ReleaseTag = New-ReleaseImageTag -GitSha $gitSha -BuildTime $buildTime
}
}
function New-ReleaseImageTag {
param(
[string]$GitSha,
[datetime]$BuildTime
)
if (-not $BuildTime) { $BuildTime = Get-Date }
if (-not $GitSha) { $GitSha = 'unknown' }
$stamp = $BuildTime.ToString('yyyyMMdd-HHmmss')
return "$stamp-$GitSha"
}
function Write-LastDockerRelease {
param(
[string]$RepoRoot,
[hashtable]$Metadata,
[string]$Image
)
$manifestPath = Join-Path $RepoRoot 'infra\deploy\last-docker-release.json'
$manifest = @{
image = $Image
release_tag = $Metadata.ReleaseTag
git_sha = $Metadata.GitSha
app_version = $Metadata.AppVersion
built_at = $Metadata.BuildTimeUtc
pushed_at = (Get-Date).ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss'Z'")
}
$manifest | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $manifestPath -Encoding UTF8
return $manifestPath
}