upgrade node
build / image (push) Successful in 3m3s

This commit is contained in:
2026-09-29 11:05:37 +02:00
parent 7b670010b1
commit fe06be8e5a
7 changed files with 50 additions and 42 deletions
+3 -1
View File
@@ -10,6 +10,8 @@ env:
IMAGE: registry.traberph.de/public/homepage IMAGE: registry.traberph.de/public/homepage
# Baked in at build time (canonical URLs); override with a repository variable. # Baked in at build time (canonical URLs); override with a repository variable.
SITE_URL: ${{ vars.SITE_URL || 'https://traberph.de' }} SITE_URL: ${{ vars.SITE_URL || 'https://traberph.de' }}
# Default Harbor instance baked into the image as an env var (overridable at runtime).
HARBOR_URL: ${{ vars.HARBOR_URL || 'https://registry.traberph.de' }}
jobs: jobs:
image: image:
@@ -50,9 +52,9 @@ jobs:
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
push: true push: true
tags: ${{ steps.tags.outputs.tags }} tags: ${{ steps.tags.outputs.tags }}
# Harbor settings are runtime env vars, so only the site URL is a build arg.
build-args: | build-args: |
SITE_URL=${{ env.SITE_URL }} SITE_URL=${{ env.SITE_URL }}
HARBOR_URL=${{ env.HARBOR_URL }}
labels: | labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }} org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ steps.tags.outputs.sha }} org.opencontainers.image.revision=${{ steps.tags.outputs.sha }}
+1 -1
View File
@@ -27,7 +27,7 @@ Consult these guides before working on related tasks:
- Node adapter (standalone), started via `server.mjs` (adds security headers). Pages are prerendered by default; `/registry/…` and `404` use `prerender = false`. - Node adapter (standalone), started via `server.mjs` (adds security headers). Pages are prerendered by default; `/registry/…` and `404` use `prerender = false`.
- Harbor data is live: `src/live.config.ts` + live loader `src/loaders/harbor.ts`, queried with `getLiveCollection()`/`getLiveEntry()`. Rendered pages are cached with `Astro.cache` (`memoryCache()`; `REGISTRY_CACHE` in `src/consts.ts`). - Harbor data is live: `src/live.config.ts` + live loader `src/loaders/harbor.ts`, queried with `getLiveCollection()`/`getLiveEntry()`. Rendered pages are cached with `Astro.cache` (`memoryCache()`; `REGISTRY_CACHE` in `src/consts.ts`).
- Harbor config comes from `astro:env/server` (all `secret`, so read at runtime, never inlined). Anonymous Harbor returns 401 for single-repo GETs; look repos up via the listing with `?q=name=…`. - Harbor config comes from `astro:env/server` (all `secret`, so read at runtime, never inlined). The Docker image sets a default `HARBOR_URL` env var from a build arg. Anonymous Harbor returns 401 for single-repo GETs; look repos up via the listing with `?q=name=…`.
- Runtime deps must be listed in `vite.ssr.noExternal` (the Docker image ships no `node_modules`). - Runtime deps must be listed in `vite.ssr.noExternal` (the Docker image ships no `node_modules`).
- Zod comes from `astro/zod` (Zod 4). - Zod comes from `astro/zod` (Zod 4).
- `astro check` needs TypeScript 6 (TS 7 is unsupported), so keep `typescript@^6`. - `astro check` needs TypeScript 6 (TS 7 is unsupported), so keep `typescript@^6`.
+6 -3
View File
@@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1.10 # syntax=docker/dockerfile:1.10
# The build output is platform-independent, so build natively (no QEMU) for multi-arch images. # The build output is platform-independent, so build natively (no QEMU) for multi-arch images.
FROM --platform=$BUILDPLATFORM node:22-alpine AS build FROM --platform=$BUILDPLATFORM node:24-alpine AS build
WORKDIR /app WORKDIR /app
RUN corepack enable RUN corepack enable
ENV ASTRO_TELEMETRY_DISABLED=1 ENV ASTRO_TELEMETRY_DISABLED=1
@@ -9,13 +9,16 @@ COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \ RUN --mount=type=cache,id=pnpm,target=/root/.local/share/pnpm/store \
pnpm install --frozen-lockfile pnpm install --frozen-lockfile
COPY . . COPY . .
# Only the canonical site URL is baked in; Harbor settings are read at runtime. # The canonical site URL is compiled in; Harbor settings are read at runtime (see below).
ARG SITE_URL ARG SITE_URL
RUN pnpm build RUN pnpm build
FROM node:22-alpine FROM node:24-alpine
WORKDIR /app WORKDIR /app
ENV NODE_ENV=production HOST=0.0.0.0 PORT=8080 ENV NODE_ENV=production HOST=0.0.0.0 PORT=8080
# Default Harbor instance; still overridable with `-e HARBOR_URL=...` at runtime.
ARG HARBOR_URL
ENV HARBOR_URL=${HARBOR_URL}
# The server build is self-contained (see `vite.ssr.noExternal`), so no node_modules. # The server build is self-contained (see `vite.ssr.noExternal`), so no node_modules.
COPY --from=build /app/dist ./dist COPY --from=build /app/dist ./dist
COPY package.json server.mjs ./ COPY package.json server.mjs ./
+6 -4
View File
@@ -43,10 +43,12 @@ Harbor settings are passed to the container at runtime, so changing them needs a
## Container (plain Docker) ## Container (plain Docker)
```sh ```sh
docker build -t homepage --build-arg SITE_URL=https://example.com . docker build -t homepage \
docker run -p 8080:8080 \ --build-arg SITE_URL=https://example.com \
-e HARBOR_URL=https://registry.example.com \ --build-arg HARBOR_URL=https://registry.example.com \
homepage .
docker run -p 8080:8080 homepage
# HARBOR_URL is baked in as a default env var; override it with -e HARBOR_URL=... if needed.
# optional robot account for non-public projects: # optional robot account for non-public projects:
# -e HARBOR_USERNAME='robot$showcase' -e HARBOR_PASSWORD=... # -e HARBOR_USERNAME='robot$showcase' -e HARBOR_PASSWORD=...
``` ```
+1
View File
@@ -9,6 +9,7 @@ services:
context: . context: .
args: args:
SITE_URL: ${SITE_URL:-} SITE_URL: ${SITE_URL:-}
HARBOR_URL: ${HARBOR_URL:-}
image: homepage:latest image: homepage:latest
restart: unless-stopped restart: unless-stopped
ports: ports:
+1 -1
View File
@@ -24,7 +24,7 @@
}, },
"devDependencies": { "devDependencies": {
"@astrojs/check": "^0.9.10", "@astrojs/check": "^0.9.10",
"@types/node": "^22.20.4", "@types/node": "^24.19.0",
"typescript": "^6.0.3" "typescript": "^6.0.3"
}, },
"private": true, "private": true,
+32 -32
View File
@@ -10,23 +10,23 @@ importers:
dependencies: dependencies:
'@astrojs/node': '@astrojs/node':
specifier: ^11.1.6 specifier: ^11.1.6
version: 11.1.6(astro@7.3.5(@types/node@22.20.4)(yaml@2.9.1)) version: 11.1.6(astro@7.3.5(@types/node@24.19.0)(yaml@2.9.1))
astro: astro:
specifier: ^7.3.5 specifier: ^7.3.5
version: 7.3.5(@types/node@22.20.4)(yaml@2.9.1) version: 7.3.5(@types/node@24.19.0)(yaml@2.9.1)
marked: marked:
specifier: ^18.0.14 specifier: ^18.0.14
version: 18.0.14 version: 18.0.14
sharp: sharp:
specifier: ^0.35.5 specifier: ^0.35.5
version: 0.35.5(@types/node@22.20.4) version: 0.35.5(@types/node@24.19.0)
devDependencies: devDependencies:
'@astrojs/check': '@astrojs/check':
specifier: ^0.9.10 specifier: ^0.9.10
version: 0.9.10(@emnapi/runtime@1.11.3)(prettier@3.9.9)(typescript@6.0.3) version: 0.9.10(@emnapi/runtime@1.11.3)(prettier@3.9.9)(typescript@6.0.3)
'@types/node': '@types/node':
specifier: ^22.20.4 specifier: ^24.19.0
version: 22.20.4 version: 24.19.0
typescript: typescript:
specifier: ^6.0.3 specifier: ^6.0.3
version: 6.0.3 version: 6.0.3
@@ -747,8 +747,8 @@ packages:
'@types/nlcst@2.0.3': '@types/nlcst@2.0.3':
resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
'@types/node@22.20.4': '@types/node@24.19.0':
resolution: {integrity: sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==} resolution: {integrity: sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==}
'@types/unist@3.0.3': '@types/unist@3.0.3':
resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
@@ -817,8 +817,8 @@ packages:
resolution: {integrity: sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==} resolution: {integrity: sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==}
hasBin: true hasBin: true
ansi-regex@6.3.0: ansi-regex@6.4.0:
resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==}
engines: {node: '>=12'} engines: {node: '>=12'}
ansi-styles@6.2.3: ansi-styles@6.2.3:
@@ -1248,8 +1248,8 @@ packages:
micromark-util-symbol@2.0.1: micromark-util-symbol@2.0.1:
resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
micromark-util-types@2.0.2: micromark-util-types@2.0.3:
resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} resolution: {integrity: sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==}
mime-db@1.54.0: mime-db@1.54.0:
resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
@@ -1532,8 +1532,8 @@ packages:
uncrypto@0.1.3: uncrypto@0.1.3:
resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
undici-types@6.21.0: undici-types@7.24.6:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==}
undici@8.11.2: undici@8.11.2:
resolution: {integrity: sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==} resolution: {integrity: sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==}
@@ -1949,10 +1949,10 @@ snapshots:
github-slugger: 2.0.0 github-slugger: 2.0.0
satteri: 0.10.5 satteri: 0.10.5
'@astrojs/node@11.1.6(astro@7.3.5(@types/node@22.20.4)(yaml@2.9.1))': '@astrojs/node@11.1.6(astro@7.3.5(@types/node@24.19.0)(yaml@2.9.1))':
dependencies: dependencies:
'@astrojs/internal-helpers': 0.11.0 '@astrojs/internal-helpers': 0.11.0
astro: 7.3.5(@types/node@22.20.4)(yaml@2.9.1) astro: 7.3.5(@types/node@24.19.0)(yaml@2.9.1)
send: 1.2.1 send: 1.2.1
server-destroy: 1.0.1 server-destroy: 1.0.1
transitivePeerDependencies: transitivePeerDependencies:
@@ -2397,9 +2397,9 @@ snapshots:
dependencies: dependencies:
'@types/unist': 3.0.3 '@types/unist': 3.0.3
'@types/node@22.20.4': '@types/node@24.19.0':
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 7.24.6
'@types/unist@3.0.3': {} '@types/unist@3.0.3': {}
@@ -2480,7 +2480,7 @@ snapshots:
dependencies: dependencies:
process-ancestry: 0.1.0 process-ancestry: 0.1.0
ansi-regex@6.3.0: {} ansi-regex@6.4.0: {}
ansi-styles@6.2.3: {} ansi-styles@6.2.3: {}
@@ -2493,7 +2493,7 @@ snapshots:
aria-query@5.3.2: {} aria-query@5.3.2: {}
astro@7.3.5(@types/node@22.20.4)(yaml@2.9.1): astro@7.3.5(@types/node@24.19.0)(yaml@2.9.1):
dependencies: dependencies:
'@astrojs/compiler-rs': 0.5.1 '@astrojs/compiler-rs': 0.5.1
'@astrojs/internal-helpers': 0.11.0 '@astrojs/internal-helpers': 0.11.0
@@ -2543,13 +2543,13 @@ snapshots:
unifont: 0.7.5 unifont: 0.7.5
unstorage: 1.17.5 unstorage: 1.17.5
verkit: 0.4.1 verkit: 0.4.1
vite: 8.3.1(@types/node@22.20.4)(esbuild@0.28.2)(yaml@2.9.1) vite: 8.3.1(@types/node@24.19.0)(esbuild@0.28.2)(yaml@2.9.1)
vitefu: 1.1.3(vite@8.3.1(@types/node@22.20.4)(esbuild@0.28.2)(yaml@2.9.1)) vitefu: 1.1.3(vite@8.3.1(@types/node@24.19.0)(esbuild@0.28.2)(yaml@2.9.1))
xxhash-wasm: 1.1.0 xxhash-wasm: 1.1.0
yargs-parser: 22.0.0 yargs-parser: 22.0.0
zod: 4.6.5 zod: 4.6.5
optionalDependencies: optionalDependencies:
sharp: 0.35.5(@types/node@22.20.4) sharp: 0.35.5(@types/node@24.19.0)
transitivePeerDependencies: transitivePeerDependencies:
- '@azure/app-configuration' - '@azure/app-configuration'
- '@azure/cosmos' - '@azure/cosmos'
@@ -2937,7 +2937,7 @@ snapshots:
micromark-util-character@2.1.1: micromark-util-character@2.1.1:
dependencies: dependencies:
micromark-util-symbol: 2.0.1 micromark-util-symbol: 2.0.1
micromark-util-types: 2.0.2 micromark-util-types: 2.0.3
micromark-util-encode@2.0.1: {} micromark-util-encode@2.0.1: {}
@@ -2949,7 +2949,7 @@ snapshots:
micromark-util-symbol@2.0.1: {} micromark-util-symbol@2.0.1: {}
micromark-util-types@2.0.2: {} micromark-util-types@2.0.3: {}
mime-db@1.54.0: {} mime-db@1.54.0: {}
@@ -3134,7 +3134,7 @@ snapshots:
setprototypeof@1.2.0: {} setprototypeof@1.2.0: {}
sharp@0.35.5(@types/node@22.20.4): sharp@0.35.5(@types/node@24.19.0):
dependencies: dependencies:
'@img/colour': 1.1.0 '@img/colour': 1.1.0
detect-libc: 2.1.2 detect-libc: 2.1.2
@@ -3165,7 +3165,7 @@ snapshots:
'@img/sharp-win32-arm64': 0.35.5 '@img/sharp-win32-arm64': 0.35.5
'@img/sharp-win32-ia32': 0.35.5 '@img/sharp-win32-ia32': 0.35.5
'@img/sharp-win32-x64': 0.35.5 '@img/sharp-win32-x64': 0.35.5
'@types/node': 22.20.4 '@types/node': 24.19.0
shiki@4.4.3: shiki@4.4.3:
dependencies: dependencies:
@@ -3206,7 +3206,7 @@ snapshots:
strip-ansi@7.2.0: strip-ansi@7.2.0:
dependencies: dependencies:
ansi-regex: 6.3.0 ansi-regex: 6.4.0
svgo@4.1.0: svgo@4.1.0:
dependencies: dependencies:
@@ -3251,7 +3251,7 @@ snapshots:
uncrypto@0.1.3: {} uncrypto@0.1.3: {}
undici-types@6.21.0: {} undici-types@7.24.6: {}
undici@8.11.2: {} undici@8.11.2: {}
@@ -3317,7 +3317,7 @@ snapshots:
'@types/unist': 3.0.3 '@types/unist': 3.0.3
vfile-message: 4.0.3 vfile-message: 4.0.3
vite@8.3.1(@types/node@22.20.4)(esbuild@0.28.2)(yaml@2.9.1): vite@8.3.1(@types/node@24.19.0)(esbuild@0.28.2)(yaml@2.9.1):
dependencies: dependencies:
lightningcss: 1.33.0 lightningcss: 1.33.0
picomatch: 4.0.7 picomatch: 4.0.7
@@ -3325,14 +3325,14 @@ snapshots:
rolldown: 1.2.11 rolldown: 1.2.11
tinyglobby: 0.2.17 tinyglobby: 0.2.17
optionalDependencies: optionalDependencies:
'@types/node': 22.20.4 '@types/node': 24.19.0
esbuild: 0.28.2 esbuild: 0.28.2
fsevents: 2.3.3 fsevents: 2.3.3
yaml: 2.9.1 yaml: 2.9.1
vitefu@1.1.3(vite@8.3.1(@types/node@22.20.4)(esbuild@0.28.2)(yaml@2.9.1)): vitefu@1.1.3(vite@8.3.1(@types/node@24.19.0)(esbuild@0.28.2)(yaml@2.9.1)):
optionalDependencies: optionalDependencies:
vite: 8.3.1(@types/node@22.20.4)(esbuild@0.28.2)(yaml@2.9.1) vite: 8.3.1(@types/node@24.19.0)(esbuild@0.28.2)(yaml@2.9.1)
volar-service-css@0.0.71(@volar/language-service@2.4.28(typescript@6.0.3)): volar-service-css@0.0.71(@volar/language-service@2.4.28(typescript@6.0.3)):
dependencies: dependencies: