Ein Laufzeit-Paket (scripts/paket-bauen.sh) für beide Wege: Next standalone, worker als Bundle mit nur den nötigen Paketen, Migrationen ohne Prisma-CLI. Compose lokal komplett hochgefahren; der Installer auf pve-demo in einem echten Debian-13-LXC durchgelaufen. Closes #019 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
80 lines
3.8 KiB
Bash
Executable File
80 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Baut das Laufzeit-Paket von ProxDeploy – dieselbe Struktur für Docker-Image und LXC-Installer:
|
||
#
|
||
# paket/
|
||
# app/ Next standalone (server.js, .next, node_modules), dazu public/, catalog/,
|
||
# prisma/migrations/ – Arbeitsverzeichnis für app und worker
|
||
# worker/worker.mjs worker als ein Bundle (esbuild); Pakete aus worker/node_modules
|
||
# worker/migrieren.mjs Migrationen ohne Prisma-CLI
|
||
# worker/node_modules/ Produktions-Abhängigkeiten, flach (ohne Symlinks)
|
||
# VERSION
|
||
#
|
||
# scripts/paket-bauen.sh [version] → paket/
|
||
# scripts/paket-bauen.sh 0.6.0 --tar → zusätzlich proxdeploy-0.6.0.tar.gz
|
||
set -euo pipefail
|
||
cd "$(dirname "$0")/.."
|
||
version="${1:-$(node -p 'require("./package.json").version')}"
|
||
commit="$(git rev-parse --short HEAD 2>/dev/null || echo unbekannt)"
|
||
|
||
rm -rf paket
|
||
mkdir -p paket/worker
|
||
|
||
# 1. Web-App (standalone). Version und Commit landen im Build (Seitenleiste, /api/v1/ich).
|
||
NEXT_PUBLIC_APP_VERSION="$version" NEXT_PUBLIC_GIT_SHA="$commit" pnpm build >/dev/null
|
||
cp -a .next/standalone paket/app
|
||
cp -a .next/static paket/app/.next/static
|
||
cp -a public paket/app/public
|
||
cp -a catalog paket/app/catalog
|
||
mkdir -p paket/app/prisma && cp -a prisma/migrations paket/app/prisma/migrations
|
||
|
||
# 2. worker und Migrationslauf als Bundles; eigener Code (inkl. Prisma-Client aus src/generated)
|
||
# wird gebündelt, Pakete bleiben extern.
|
||
for eintrag in "src/worker/main.ts:worker.mjs" "src/betrieb/migrieren-start.ts:migrieren.mjs"; do
|
||
pnpm exec esbuild "${eintrag%%:*}" --bundle --platform=node --format=esm --target=node24 \
|
||
--packages=external --log-level=warning \
|
||
--define:process.env.NEXT_PUBLIC_APP_VERSION="\"$version\"" \
|
||
--define:process.env.NEXT_PUBLIC_GIT_SHA="\"$commit\"" \
|
||
--metafile="paket/worker/${eintrag##*:}.meta.json" \
|
||
--outfile="paket/worker/${eintrag##*:}"
|
||
done
|
||
|
||
# 3. Nur die Pakete, die die Bundles wirklich importieren (aus den esbuild-Metadateien), in den
|
||
# Versionen aus package.json – flach, ohne Build-Skripte. Next, React & Co. braucht der worker nicht.
|
||
tmp="$(mktemp -d)"
|
||
node - "$tmp" paket/worker/*.meta.json <<'JS'
|
||
const fs = require("node:fs");
|
||
const [ziel, ...metas] = process.argv.slice(2);
|
||
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
||
const benoetigt = new Set();
|
||
for (const datei of metas) {
|
||
const meta = JSON.parse(fs.readFileSync(datei, "utf8"));
|
||
for (const eingabe of Object.values(meta.inputs))
|
||
for (const imp of eingabe.imports ?? [])
|
||
if (imp.external && !imp.path.startsWith("node:")) {
|
||
const teile = imp.path.split("/");
|
||
benoetigt.add(imp.path.startsWith("@") ? teile.slice(0, 2).join("/") : teile[0]);
|
||
}
|
||
}
|
||
const abhaengigkeiten = {};
|
||
for (const name of [...benoetigt].sort()) {
|
||
if (!pkg.dependencies[name]) throw new Error(`${name} wird vom worker importiert, steht aber nicht in dependencies`);
|
||
// Exakt die Version, die in der Entwicklung installiert ist (aus dem Lockfile aufgelöst).
|
||
abhaengigkeiten[name] = JSON.parse(fs.readFileSync(`node_modules/${name}/package.json`, "utf8")).version;
|
||
}
|
||
fs.writeFileSync(`${ziel}/package.json`, JSON.stringify({ name: "proxdeploy-worker", private: true, type: "module", dependencies: abhaengigkeiten }, null, 2));
|
||
console.log(`worker braucht: ${Object.entries(abhaengigkeiten).map(([n, v]) => `${n}@${v}`).join(", ")}`);
|
||
JS
|
||
rm -f paket/worker/*.meta.json
|
||
cp pnpm-workspace.yaml "$tmp/"
|
||
(cd "$tmp" && pnpm install --prod --ignore-scripts --config.node-linker=hoisted >/dev/null)
|
||
mv "$tmp/node_modules" paket/worker/node_modules
|
||
rm -rf "$tmp"
|
||
|
||
echo "$version+$commit" > paket/VERSION
|
||
echo "paket/ gebaut ($version+$commit, $(du -sh paket | cut -f1))"
|
||
|
||
if [ "${2:-}" = "--tar" ]; then
|
||
tar -czf "proxdeploy-$version.tar.gz" -C paket .
|
||
sha256sum "proxdeploy-$version.tar.gz"
|
||
fi
|