Namen getauscht: das Standard-Compose zieht jetzt die fertigen Registry-Images (vorher docker-compose.prod.yml), die Build-Variante heisst docker-compose.dev.yml. Weniger verwirrend, weil der Produktivfall ohne -f auskommt. Kopfkommentare, README, CLAUDE.md, .env.example und build-push-images.mjs entsprechend angepasst. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
57 lines
2.5 KiB
JavaScript
57 lines
2.5 KiB
JavaScript
#!/usr/bin/env node
|
|
// Build the three NovaSonic images and push them to your registry, so the production host just PULLS
|
|
// (docker-compose.yml) instead of building (that's docker-compose.dev.yml). Run from your dev machine:
|
|
//
|
|
// npm run push-images # builds + pushes REGISTRY/*:TAG (and :latest)
|
|
//
|
|
// Config (env or a gitignored scripts/.env.release / repo .env):
|
|
// REGISTRY e.g. gitea.honeyy.duckdns.org/docker (Gitea uses a LOWERCASE owner)
|
|
// TAG image tag (default: latest)
|
|
// You must `docker login <registry-host>` once first. Plain-HTTP internal registries also need the
|
|
// daemon's insecure-registries list (see .env.example).
|
|
|
|
import { spawnSync } from 'node:child_process';
|
|
import { readFileSync, existsSync } from 'node:fs';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { dirname, join, resolve } from 'node:path';
|
|
|
|
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
|
|
// Load REGISTRY/TAG from a local env file if present (repo .env, then scripts/.env.release).
|
|
for (const f of [join(root, '.env'), join(root, 'scripts', '.env.release')]) {
|
|
if (!existsSync(f)) continue;
|
|
for (const line of readFileSync(f, 'utf8').split('\n')) {
|
|
const m = line.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*)\s*$/i);
|
|
if (m && !(m[1] in process.env)) process.env[m[1]] = m[2].replace(/^["']|["']$/g, '');
|
|
}
|
|
}
|
|
|
|
const REGISTRY = (process.env.REGISTRY || '').replace(/\/$/, '');
|
|
const TAG = process.env.TAG || 'latest';
|
|
if (!REGISTRY) { console.error('\n✖ REGISTRY muss gesetzt sein (env oder .env). Siehe .env.example.'); process.exit(1); }
|
|
|
|
// name → build context (relative to repo root). Frontend uses the root Dockerfile.
|
|
const images = {
|
|
'novasonic-frontend': '.',
|
|
'novasonic-backend': 'backend',
|
|
'novasonic-scrobble': 'scrobble',
|
|
};
|
|
|
|
function run(cmd, args) {
|
|
console.log(`\n$ ${cmd} ${args.join(' ')}`);
|
|
const r = spawnSync(cmd, args, { cwd: root, stdio: 'inherit', shell: process.platform === 'win32' });
|
|
if (r.status !== 0) { console.error(`\n✖ Fehlgeschlagen: ${cmd} ${args.join(' ')}`); process.exit(1); }
|
|
}
|
|
|
|
for (const [name, ctx] of Object.entries(images)) {
|
|
const ref = `${REGISTRY}/${name}:${TAG}`;
|
|
const latest = `${REGISTRY}/${name}:latest`;
|
|
console.log(`\n=== ${name} → ${ref} ===`);
|
|
run('docker', ['build', '-t', ref, '-t', latest, ctx]);
|
|
run('docker', ['push', ref]);
|
|
if (latest !== ref) run('docker', ['push', latest]);
|
|
}
|
|
|
|
console.log(`\n✔ Alle Images gebaut + gepusht (${REGISTRY}/*:${TAG}). Auf dem Server:`);
|
|
console.log(' docker compose pull && docker compose up -d');
|