From 80ecad6dddce496bdd4bdd1c3111abdd6b667735 Mon Sep 17 00:00:00 2001 From: seb Date: Tue, 27 Oct 2026 16:20:02 +0100 Subject: [PATCH] u --- Dockerfile | 9 --------- docker-compose.yml | 37 ------------------------------------- scripts/buildSea.js | 15 +++++---------- src/sea-entry.cjs | 21 ++------------------- start-docker.sh | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 75 deletions(-) delete mode 100644 docker-compose.yml create mode 100755 start-docker.sh diff --git a/Dockerfile b/Dockerfile index 665c0f9..9f01dd4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,15 +15,6 @@ COPY --from=syslibs /usr/lib/x86_64-linux-gnu/libfontconfig.so* /usr/lib/x86_64- COPY --from=syslibs /usr/lib/x86_64-linux-gnu/libxml2.so* /usr/lib/x86_64-linux-gnu/ COPY --from=syslibs /usr/lib/x86_64-linux-gnu/libfribidi.so* /usr/lib/x86_64-linux-gnu/ -# The standalone SEA binary contains Node.js runtime, src/, package.json, and all app logic -COPY dist/dashback ./dist/dashback - -# Only native C++ addon packages required by OS dynamic linker (dlopen) -COPY node_modules/better-sqlite3 ./node_modules/better-sqlite3 -COPY node_modules/canvas ./node_modules/canvas -COPY node_modules/@img ./node_modules/@img -COPY node_modules/sharp ./node_modules/sharp - # Set production defaults: port 4208 ENV NODE_ENV=production \ HOST=0.0.0.0 \ diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index bf7c102..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,37 +0,0 @@ -services: - dashback: - build: - context: . - dockerfile: Dockerfile - image: dashback:latest - container_name: dashback - read_only: true - user: "${UID:-1000}:${GID:-1000}" - tmpfs: - - /tmp:rw,noexec,nosuid,size=512m - - /run:rw,noexec,nosuid,size=16m - networks: - - dash_net - ports: - - "127.0.0.1:4208:4208" - environment: - - HOST=0.0.0.0 - - PORT=4208 - - HTTPS_PORT=0 - - MSSQL_SERVER=sql_server - - HEALTH_MONITOR_ENABLED=false - - SQLITE_PATH=/app/data/dash.db - - STORAGE_DIR=/app/data/storage - - BACKUP_DIR=/app/data/backups - # If a .env file is present, its values will be loaded: - env_file: - - path: .env - required: false - volumes: - # Writable data directory - - ./data:/app/data:rw - restart: unless-stopped - -networks: - dash_net: - external: true diff --git a/scripts/buildSea.js b/scripts/buildSea.js index 0781cb8..2008fcf 100644 --- a/scripts/buildSea.js +++ b/scripts/buildSea.js @@ -18,10 +18,7 @@ if (!fs.existsSync(distDir)) { fs.mkdirSync(distDir, { recursive: true }); } -console.log('Packaging application, siblings, and JavaScript dependencies into SEA payload...'); - -// Native C++ addon folders that will be loaded from the host filesystem via dlopen -const NATIVE_ADDON_PKGS = new Set(['better-sqlite3', 'canvas', 'sharp', '@img']); +console.log('Packaging application, siblings, and dependencies into SEA payload...'); function packDirectory(dir, prefix, result) { if (!fs.existsSync(dir)) return; @@ -30,11 +27,10 @@ function packDirectory(dir, prefix, result) { const full = path.join(dir, entry.name); const rel = path.join(prefix, entry.name); if (entry.isDirectory()) { - if (entry.name === 'test' || entry.name === 'tests' || entry.name === 'docs' || entry.name === '.github' || entry.name === '.git') continue; + if (entry.name === 'test' || entry.name === 'tests' || entry.name === 'docs' || entry.name === '.github' || entry.name === '.git' || entry.name === 'obj.target') continue; packDirectory(full, rel, result); } else if (entry.isFile()) { - // Ignore compiled native binary extensions which are linked from the host - if (entry.name.endsWith('.node') || entry.name.endsWith('.so') || entry.name.endsWith('.dylib') || entry.name.endsWith('.dll') || entry.name.endsWith('.a')) continue; + if (entry.name.endsWith('.a') || entry.name.endsWith('.o') || entry.name.endsWith('.cc') || entry.name.endsWith('.cpp') || entry.name.endsWith('.c') || entry.name.endsWith('.h')) continue; result[rel] = fs.readFileSync(full).toString('base64'); } } @@ -67,15 +63,14 @@ if (fs.existsSync(path.join(llmorbiterDir, 'src'))) { } } -// 3. Pack all non-native node_modules dependencies +// 3. Pack all node_modules dependencies function packNodeModules(nmPath) { if (!fs.existsSync(nmPath)) return; for (const name of fs.readdirSync(nmPath)) { - if (NATIVE_ADDON_PKGS.has(name) || name.startsWith('.') || name === 'libdashstore' || name === 'libllmorbiter') continue; + if (name.startsWith('.') || name === 'libdashstore' || name === 'libllmorbiter') continue; const pkgDir = path.join(nmPath, name); if (name.startsWith('@')) { for (const sub of fs.readdirSync(pkgDir)) { - if (NATIVE_ADDON_PKGS.has(sub) || NATIVE_ADDON_PKGS.has(`${name}/${sub}`)) continue; packDirectory(path.join(pkgDir, sub), `node_modules/${name}/${sub}`, payload); } } else { diff --git a/src/sea-entry.cjs b/src/sea-entry.cjs index 841923c..f9b8596 100644 --- a/src/sea-entry.cjs +++ b/src/sea-entry.cjs @@ -2,8 +2,8 @@ * SEA Entry point for dashback. * Embedded inside the Node.js single executable binary. * - * Unpacks the bundled application, sibling packages, and JavaScript dependencies - * to a runtime directory, and links only the native C++ addons from the host. + * Unpacks the bundled application, sibling packages, and all dependencies + * (including native C++ addons) to a runtime directory. */ const sea = require('node:sea'); const fs = require('node:fs'); @@ -32,23 +32,6 @@ function getProjectRoot() { fs.writeFileSync(markerFile, '1'); } - // Link host native addons into runtime node_modules - const hostNodeModules = path.resolve(process.cwd(), 'node_modules'); - const runtimeNodeModules = path.join(runtimeDir, 'node_modules'); - fs.mkdirSync(runtimeNodeModules, { recursive: true }); - - const NATIVE_ADDON_DIRS = ['better-sqlite3', 'canvas', 'sharp', '@img']; - for (const addon of NATIVE_ADDON_DIRS) { - const hostAddon = path.join(hostNodeModules, addon); - const targetAddon = path.join(runtimeNodeModules, addon); - if (fs.existsSync(hostAddon) && !fs.existsSync(targetAddon)) { - try { - fs.mkdirSync(path.dirname(targetAddon), { recursive: true }); - fs.symlinkSync(hostAddon, targetAddon, 'junction'); - } catch {} - } - } - // Link host .env if present so config/env.js can find it const hostEnv = path.resolve(process.cwd(), '.env'); const runtimeEnv = path.join(runtimeDir, '.env'); diff --git a/start-docker.sh b/start-docker.sh new file mode 100755 index 0000000..0ec10eb --- /dev/null +++ b/start-docker.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Ensure the writable data directory exists on the host +mkdir -p "${SCRIPT_DIR}/data" + +ENV_ARGS=() +if [ -f "${SCRIPT_DIR}/.env" ]; then + ENV_ARGS+=(--env-file "${SCRIPT_DIR}/.env") +fi + +docker run -d \ + --name dashback \ + --restart unless-stopped \ + --read-only \ + --user "$(id -u):$(id -g)" \ + --tmpfs /tmp:rw,exec,nosuid,size=512m \ + --tmpfs /run:rw,noexec,nosuid,size=16m \ + -p 127.0.0.1:4608:4208 \ + -e HOST=0.0.0.0 \ + -e PORT=4208 \ + -e HTTPS_PORT=0 \ + -e HEALTH_MONITOR_ENABLED=false \ + -e SQLITE_PATH=/app/data/dash.db \ + -e STORAGE_DIR=/app/data/storage \ + -e BACKUP_DIR=/app/data/backups \ + "${ENV_ARGS[@]}" \ + -v "${SCRIPT_DIR}/dist/dashback:/app/dist/dashback:ro" \ + -v "${SCRIPT_DIR}/data:/app/data:rw" \ + dashback:latest +