From a7d3e4ff18f772c3163b54e74c6611ed1245c20b Mon Sep 17 00:00:00 2001 From: CREDO23 Date: Fri, 24 Apr 2026 19:15:02 +0200 Subject: [PATCH] Extend desktop package scripts and local dependency compose --- docker/docker-compose.deps-only.yml | 123 ++++++++++++++++++ surfsense_desktop/README.md | 5 +- surfsense_desktop/package.json | 4 +- surfsense_desktop/scripts/electron-dev.mjs | 24 ++++ .../scripts/postinstall-rebuild.mjs | 25 ++++ 5 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 docker/docker-compose.deps-only.yml create mode 100644 surfsense_desktop/scripts/electron-dev.mjs create mode 100644 surfsense_desktop/scripts/postinstall-rebuild.mjs diff --git a/docker/docker-compose.deps-only.yml b/docker/docker-compose.deps-only.yml new file mode 100644 index 000000000..ee09a4d5b --- /dev/null +++ b/docker/docker-compose.deps-only.yml @@ -0,0 +1,123 @@ +# ============================================================================= +# SurfSense — Dependencies only (no backend / frontend / Celery images) +# ============================================================================= +# Postgres, Redis, SearXNG, pgAdmin, Zero — run API + Next + Celery on the host. +# Celery is not Dockerized here: use `uv run` from surfsense_backend/ (no extra +# backend image build just for workers). +# +# From repo root (SurfSense/): +# docker compose -f docker/docker-compose.deps-only.yml up -d +# +# Compose variable substitution uses `docker/.env` (copy from .env.example). +# Bind mounts use ./postgresql.conf and ./searxng in this directory. +# +# Local Celery (from surfsense_backend/, after Redis is up): +# uv run celery -A celery_worker.celery_app worker --loglevel=info --concurrency=1 --pool=solo --queues=surfsense,surfsense.connectors +# uv run celery -A celery_worker.celery_app beat --loglevel=info +# +# Host setup: +# - Backend .env: DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/surfsense +# - Backend .env: SEARXNG_DEFAULT_HOST=http://localhost:${SEARXNG_PORT:-8888} +# - Backend .env: CELERY_BROKER_URL / REDIS_APP_URL → redis://localhost:6379/0 +# - Web .env: NEXT_PUBLIC_ZERO_CACHE_URL=http://localhost:${ZERO_CACHE_PORT:-4848} +# ============================================================================= + +name: surfsense-deps + +services: + db: + image: pgvector/pgvector:pg17 + ports: + - "${POSTGRES_PORT:-5432}:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + - ./postgresql.conf:/etc/postgresql/postgresql.conf:ro + environment: + - POSTGRES_USER=${DB_USER:-postgres} + - POSTGRES_PASSWORD=${DB_PASSWORD:-postgres} + - POSTGRES_DB=${DB_NAME:-surfsense} + command: postgres -c config_file=/etc/postgresql/postgresql.conf + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-surfsense}"] + interval: 10s + timeout: 5s + retries: 5 + + pgadmin: + image: dpage/pgadmin4 + ports: + - "${PGADMIN_PORT:-5050}:80" + environment: + - PGADMIN_DEFAULT_EMAIL=${PGADMIN_DEFAULT_EMAIL:-admin@surfsense.com} + - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_DEFAULT_PASSWORD:-surfsense} + volumes: + - pgadmin_data:/var/lib/pgadmin + depends_on: + - db + + redis: + image: redis:8-alpine + ports: + - "${REDIS_PORT:-6379}:6379" + volumes: + - redis_data:/data + command: redis-server --appendonly yes + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + + searxng: + image: searxng/searxng:2026.3.13-3c1f68c59 + ports: + - "${SEARXNG_PORT:-8888}:8080" + volumes: + - ./searxng:/etc/searxng + environment: + - SEARXNG_SECRET=${SEARXNG_SECRET:-surfsense-searxng-secret} + healthcheck: + test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/healthz"] + interval: 10s + timeout: 5s + retries: 5 + + zero-cache: + image: rocicorp/zero:0.26.2 + ports: + - "${ZERO_CACHE_PORT:-4848}:4848" + extra_hosts: + - "host.docker.internal:host-gateway" + depends_on: + db: + condition: service_healthy + environment: + - ZERO_UPSTREAM_DB=postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@db:5432/${DB_NAME:-surfsense}?sslmode=${DB_SSLMODE:-disable} + - ZERO_CVR_DB=postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@db:5432/${DB_NAME:-surfsense}?sslmode=${DB_SSLMODE:-disable} + - ZERO_CHANGE_DB=postgresql://${DB_USER:-postgres}:${DB_PASSWORD:-postgres}@db:5432/${DB_NAME:-surfsense}?sslmode=${DB_SSLMODE:-disable} + - ZERO_REPLICA_FILE=/data/zero.db + - ZERO_ADMIN_PASSWORD=${ZERO_ADMIN_PASSWORD:-surfsense-zero-admin} + - ZERO_APP_PUBLICATIONS=${ZERO_APP_PUBLICATIONS:-zero_publication} + - ZERO_NUM_SYNC_WORKERS=${ZERO_NUM_SYNC_WORKERS:-4} + - ZERO_UPSTREAM_MAX_CONNS=${ZERO_UPSTREAM_MAX_CONNS:-20} + - ZERO_CVR_MAX_CONNS=${ZERO_CVR_MAX_CONNS:-30} + - ZERO_QUERY_URL=${ZERO_QUERY_URL:-http://host.docker.internal:3000/api/zero/query} + - ZERO_MUTATE_URL=${ZERO_MUTATE_URL:-http://host.docker.internal:3000/api/zero/mutate} + volumes: + - zero_cache_data:/data + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:4848/keepalive"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + postgres_data: + name: surfsense-deps-postgres + pgadmin_data: + name: surfsense-deps-pgadmin + redis_data: + name: surfsense-deps-redis + zero_cache_data: + name: surfsense-deps-zero-cache diff --git a/surfsense_desktop/README.md b/surfsense_desktop/README.md index 80efefba8..0f7a99e93 100644 --- a/surfsense_desktop/README.md +++ b/surfsense_desktop/README.md @@ -17,6 +17,8 @@ pnpm dev This starts the Next.js dev server and Electron concurrently. Hot reload works — edit the web app and changes appear immediately. +On **Linux**, `pnpm dev` runs Electron through `scripts/electron-dev.mjs`: it sets `ELECTRON_DISABLE_SANDBOX=1` for the sandbox issue and passes **`--ozone-platform=x11`** (XWayland) unless **`SURFSENSE_ELECTRON_WAYLAND=1`** is set, so dev tends to behave closer to X11 for shortcuts and Ozone. Packaged Linux builds are unchanged. + ## Configuration Two `.env` files control the build: @@ -43,12 +45,13 @@ cd ../surfsense_desktop pnpm build ``` -**Step 3** — Package into a distributable: +**Step 3** — Package into a distributable (after steps 1–2): ```bash pnpm dist:mac # macOS (.dmg + .zip) pnpm dist:win # Windows (.exe) pnpm dist:linux # Linux (.deb + .AppImage) +pnpm pack:dir # optional: unpacked app only → release/… (run that binary yourself) ``` **Step 4** — Find the output: diff --git a/surfsense_desktop/package.json b/surfsense_desktop/package.json index 638fd3ffc..7f787c373 100644 --- a/surfsense_desktop/package.json +++ b/surfsense_desktop/package.json @@ -4,7 +4,7 @@ "description": "SurfSense Desktop App", "main": "dist/main.js", "scripts": { - "dev": "pnpm build && concurrently -k \"pnpm --dir ../surfsense_web dev\" \"wait-on http://localhost:3000 && electron .\"", + "dev": "pnpm build && concurrently -k \"pnpm --dir ../surfsense_web dev\" \"wait-on http://localhost:3000 && node scripts/electron-dev.mjs\"", "build": "node scripts/build-electron.mjs", "pack:dir": "pnpm build && electron-builder --dir --config electron-builder.yml", "dist": "pnpm build && electron-builder --config electron-builder.yml", @@ -12,7 +12,7 @@ "dist:win": "pnpm build && electron-builder --win --config electron-builder.yml", "dist:linux": "pnpm build && electron-builder --linux --config electron-builder.yml", "typecheck": "tsc --noEmit", - "postinstall": "electron-rebuild" + "postinstall": "node scripts/postinstall-rebuild.mjs" }, "homepage": "https://github.com/MODSetter/SurfSense", "author": { diff --git a/surfsense_desktop/scripts/electron-dev.mjs b/surfsense_desktop/scripts/electron-dev.mjs new file mode 100644 index 000000000..64be03211 --- /dev/null +++ b/surfsense_desktop/scripts/electron-dev.mjs @@ -0,0 +1,24 @@ +/** + * Linux dev: (1) ELECTRON_DISABLE_SANDBOX before start — setuid chrome-sandbox in node_modules. + * (2) --ozone-platform=x11 — use X11 via XWayland so global shortcuts / GPU warnings match many + * Linux Electron setups better than native Wayland. Set SURFSENSE_ELECTRON_WAYLAND=1 to skip (2). + * Packaged apps are not launched through this script. + */ +import { spawnSync } from 'child_process'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + +const root = join(dirname(fileURLToPath(import.meta.url)), '..'); +const cli = join(root, 'node_modules', 'electron', 'cli.js'); + +const env = { ...process.env }; +const args = [cli, '.']; +if (process.platform === 'linux') { + env.ELECTRON_DISABLE_SANDBOX = '1'; + if (env.SURFSENSE_ELECTRON_WAYLAND !== '1') { + args.push('--ozone-platform=x11'); + } +} + +const r = spawnSync(process.execPath, args, { cwd: root, env, stdio: 'inherit' }); +process.exit(r.status === null ? 1 : r.status ?? 0); diff --git a/surfsense_desktop/scripts/postinstall-rebuild.mjs b/surfsense_desktop/scripts/postinstall-rebuild.mjs new file mode 100644 index 000000000..d1cfd0732 --- /dev/null +++ b/surfsense_desktop/scripts/postinstall-rebuild.mjs @@ -0,0 +1,25 @@ +/** + * node-mac-permissions is macOS-only; electron-rebuild would still compile it on Linux/Windows + * (missing `make`, wrong platform). We skip rebuild there. + */ +import { existsSync } from 'fs'; +import { spawnSync } from 'child_process'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + +const root = join(dirname(fileURLToPath(import.meta.url)), '..'); + +if (process.platform !== 'darwin') { + console.log('[surfsense-desktop] Skipping electron-rebuild on non-macOS (native permissions module is darwin-only).'); + process.exit(0); +} + +const bin = join(root, 'node_modules', '.bin', 'electron-rebuild'); + +if (!existsSync(bin)) { + console.warn('[surfsense-desktop] electron-rebuild not found in node_modules/.bin, skipping.'); + process.exit(0); +} + +const result = spawnSync(bin, [], { cwd: root, stdio: 'inherit' }); +process.exit(result.status === null ? 1 : result.status);