sync: update from private repo (11e2d76)
Some checks failed
CI / build-and-test (push) Has been cancelled
Some checks failed
CI / build-and-test (push) Has been cancelled
This commit is contained in:
parent
ee062050e0
commit
ef44e1a5d9
41
Dockerfile
41
Dockerfile
@ -33,17 +33,32 @@ COPY scripts ./scripts
|
|||||||
RUN npm run build:server
|
RUN npm run build:server
|
||||||
RUN npm run build:ui
|
RUN npm run build:ui
|
||||||
|
|
||||||
FROM node:22-alpine AS runtime
|
# Runtime is Debian (NOT Alpine): the noVNC headed-browser stack needs glibc.
|
||||||
|
# Playwright's bundled Chromium does not run on Alpine/musl, and Xvfb/x11vnc/
|
||||||
|
# websockify + Chromium are well-supported on Debian. The builder stage stays
|
||||||
|
# Alpine because it only emits portable artifacts (dist/, ui/dist, vendor/).
|
||||||
|
FROM node:22-bookworm-slim AS runtime
|
||||||
|
|
||||||
RUN apk add --no-cache \
|
# System deps:
|
||||||
|
# - git/ca-certificates/tzdata/bash: app + git ops + the bash sandbox shell
|
||||||
|
# - bubblewrap/python3/python3-pip: sandboxed bash + pre-baked python tools
|
||||||
|
# - xvfb/x11vnc/websockify: the noVNC display stack (display_mode: novnc) that
|
||||||
|
# powers the Browser tab live view, InteractiveBrowse, and the CAPTCHA pool
|
||||||
|
# - fonts-*: legible text (incl. CJK) in the headed browser / screenshots
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
git \
|
git \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
tzdata \
|
tzdata \
|
||||||
bash \
|
bash \
|
||||||
bubblewrap \
|
bubblewrap \
|
||||||
python3 \
|
python3 \
|
||||||
py3-pip \
|
python3-pip \
|
||||||
&& apk add --no-cache --virtual .native-build-deps build-base
|
xvfb \
|
||||||
|
x11vnc \
|
||||||
|
websockify \
|
||||||
|
fonts-liberation \
|
||||||
|
fonts-noto-cjk \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Pre-bake python packages into the system site-packages (read-only bind-mounted
|
# Pre-bake python packages into the system site-packages (read-only bind-mounted
|
||||||
# into every bash sandbox). Runtime `pip install` is intentionally unsupported.
|
# into every bash sandbox). Runtime `pip install` is intentionally unsupported.
|
||||||
@ -53,10 +68,24 @@ RUN pip3 install --no-cache-dir --break-system-packages -r /tmp/python-requireme
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Shared, world-readable Playwright browser cache so the non-root `node` user can
|
||||||
|
# launch Chromium (npm ci's playwright postinstall downloads it here).
|
||||||
|
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
|
||||||
|
|
||||||
COPY package.json package-lock.json* ./
|
COPY package.json package-lock.json* ./
|
||||||
RUN npm ci --omit=dev \
|
# build-essential compiles better-sqlite3's native addon (removed afterward to
|
||||||
|
# stay lean). `npm ci` also runs Playwright's postinstall → downloads Chromium
|
||||||
|
# into PLAYWRIGHT_BROWSERS_PATH. `playwright install-deps chromium` then adds the
|
||||||
|
# Chromium shared-library apt deps. chmod makes the browser readable by `node`.
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends build-essential \
|
||||||
|
&& npm ci --omit=dev \
|
||||||
|
&& npx playwright install-deps chromium \
|
||||||
|
&& chmod -R go+rX /ms-playwright \
|
||||||
&& npm cache clean --force \
|
&& npm cache clean --force \
|
||||||
&& apk del .native-build-deps
|
&& apt-get purge -y build-essential \
|
||||||
|
&& apt-get autoremove -y \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY --from=builder /app/dist ./dist
|
COPY --from=builder /app/dist ./dist
|
||||||
COPY --from=builder /app/ui/dist ./ui/dist
|
COPY --from=builder /app/ui/dist ./ui/dist
|
||||||
|
|||||||
@ -6,6 +6,10 @@ services:
|
|||||||
image: maestro:latest
|
image: maestro:latest
|
||||||
container_name: maestro
|
container_name: maestro
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
# Headed Chromium (display_mode: novnc) crashes with Docker's default 64MB
|
||||||
|
# /dev/shm. Give it room so the Browser tab / InteractiveBrowse / CAPTCHA
|
||||||
|
# pool work. Harmless when display_mode is headless.
|
||||||
|
shm_size: "1gb"
|
||||||
ports:
|
ports:
|
||||||
# Auth is optional, so keep the default deployment local-only.
|
# Auth is optional, so keep the default deployment local-only.
|
||||||
- "127.0.0.1:9876:9876"
|
- "127.0.0.1:9876:9876"
|
||||||
|
|||||||
@ -108,14 +108,30 @@ export class SessionManager extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isAvailable(): boolean {
|
static isAvailable(): boolean {
|
||||||
|
// Use the POSIX shell builtin `command -v`, NOT the external `which` binary.
|
||||||
|
// `which` is absent in some minimal images (e.g. debian-slim dropped it from
|
||||||
|
// debianutils) and depends on PATH; relying on it caused "deps missing →
|
||||||
|
// headless fallback" even when Xvfb/x11vnc/websockify were actually installed.
|
||||||
|
// `command -v` is built into /bin/sh, so execSync (which runs via `/bin/sh -c`)
|
||||||
|
// resolves each binary from the server process's own PATH.
|
||||||
|
const required = ['Xvfb', 'x11vnc', 'websockify'];
|
||||||
|
const missing: string[] = [];
|
||||||
|
for (const bin of required) {
|
||||||
try {
|
try {
|
||||||
execSync('which Xvfb', { stdio: 'ignore' });
|
execSync(`command -v ${bin}`, { stdio: 'ignore' });
|
||||||
execSync('which x11vnc', { stdio: 'ignore' });
|
|
||||||
execSync('which websockify', { stdio: 'ignore' });
|
|
||||||
return true;
|
|
||||||
} catch {
|
} catch {
|
||||||
|
missing.push(bin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (missing.length > 0) {
|
||||||
|
logger.warn(
|
||||||
|
`[SessionManager] noVNC display stack unavailable; not found on the server PATH: ${missing.join(', ')}. ` +
|
||||||
|
`Browser/CAPTCHA live view (display_mode: novnc) falls back to headless. ` +
|
||||||
|
`Install them (scripts/setup-novnc.sh) and ensure they are on the server process's PATH.`,
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private cleanupOrphanedProcesses(): void {
|
private cleanupOrphanedProcesses(): void {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user