# ----------------------------------------------------------------------------- # Runtime image with Node.js, Python, optional Chromium, and the API. # ----------------------------------------------------------------------------- FROM node:22-bookworm-slim # Build variant: "core" | "browser" | "full" # core — Python + MaskanX + Telegram only (no Chromium, no optional channels) # browser — core + Chromium/xvfb + Playwright/PinchTab/agent-browser # full — browser + Feishu/Discord/DingTalk channels + desktop tools ARG MASKANX_VARIANT=full # Pip extras to install (overrides variant default if provided). # Variant defaults: core="[local]", browser="[browser,local]", full="[all,local]" ARG MASKANX_PIP_EXTRAS="" # Preload default local embedding model during image build by default. ARG MASKANX_PRELOAD_EMBEDDINGS=1 # ENV variables ENV NODE_ENV=production ENV WORKSPACE_DIR=/app ENV ADCLAW_WORKING_DIR=/app/working ENV HF_HOME=/app/model-cache/huggingface ENV SENTENCE_TRANSFORMERS_HOME=/app/model-cache/sentence-transformers ENV ADCLAW_MEMORY_MANAGER_START_MODE=background ENV ADCLAW_ENABLE_REME=0 ENV ADCLAW_REME_LIGHT_TOKEN_COUNTER=1 ENV ADCLAW_MEMORY_MANAGER_BACKGROUND_DELAY_SECONDS=5 ENV ADCLAW_MEMORY_MANAGER_MAX_LOADAVG=2.0 ENV ADCLAW_MEMORY_COMPACT_BATCH_MESSAGES=80 ENV ADCLAW_REME_RETENTION_DAYS=30 ENV MEMORY_STORE_BACKEND=sqlite ENV FTS_ENABLED=true # Default enabled channels (can be overridden at runtime with -e MASKANX_ENABLED_CHANNELS=...). ARG MASKANX_ENABLED_CHANNELS="discord,dingtalk,feishu,qq,console,telegram" ENV MASKANX_ENABLED_CHANNELS=${MASKANX_ENABLED_CHANNELS} ENV ADCLAW_ENABLED_CHANNELS=${MASKANX_ENABLED_CHANNELS} ARG DEBIAN_FRONTEND=noninteractive # ----------------------------------------------------------------------------- # Base system packages (all variants) # ----------------------------------------------------------------------------- RUN apt-get update && apt-get install -y --fix-missing \ curl \ python3 \ python3-pip \ python3-venv \ build-essential \ libssl-dev \ git \ supervisor \ vim \ gettext-base \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean # ----------------------------------------------------------------------------- # Browser stack (only for browser/full variants) # ----------------------------------------------------------------------------- RUN if [ "$MASKANX_VARIANT" != "core" ]; then \ apt-get update && apt-get install -y --fix-missing \ xfce4 \ xfce4-terminal \ xvfb \ dbus-x11 \ fonts-wqy-zenhei \ fonts-wqy-microhei \ chromium \ chromium-sandbox \ libx11-xcb1 \ libxcomposite1 \ libxdamage1 \ libxext6 \ libxfixes3 \ libxi6 \ libxtst6 \ libnss3 \ libglib2.0-0 \ libdrm2 \ libgbm1 \ libasound2 \ fonts-liberation \ libu2f-udev \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean \ && sed -i 's/^CHROMIUM_FLAGS=""/CHROMIUM_FLAGS="--no-sandbox"/' /usr/bin/chromium ; \ fi # PinchTab: token-efficient browser control for AI agents (browser/full only). RUN if [ "$MASKANX_VARIANT" != "core" ]; then \ curl -fsSL https://pinchtab.com/install.sh | bash \ && cp /root/.pinchtab/bin/*/pinchtab-linux-* /usr/local/bin/pinchtab-bin \ && chmod 755 /usr/local/bin/pinchtab-bin ; \ fi ENV PINCHTAB_PORT=9867 # agent-browser: install CLI globally (browser/full only). RUN if [ "$MASKANX_VARIANT" != "core" ]; then \ npm install -g agent-browser sitefetch ; \ fi # Browser env vars (harmless if binaries missing) ENV AGENT_BROWSER_EXECUTABLE_PATH=/usr/bin/chromium ENV PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 ENV ADCLAW_RUNNING_IN_CONTAINER=1 ENV MASKANX_VARIANT=${MASKANX_VARIANT} ENV ADCLAW_VARIANT=${MASKANX_VARIANT} WORKDIR ${WORKSPACE_DIR} RUN python3 -m venv venv ENV PATH="/app/venv/bin:$PATH" COPY pyproject.toml README.md ./ COPY src ./src # Install CPU-only PyTorch first (avoids downloading 2GB CUDA build), # then install app with variant-specific extras. # core → [local] — Python + MaskanX + AOM embeddings # browser → [browser,local] — + Playwright # full → [all,local] — + all optional channels + desktop tools # MASKANX_PIP_EXTRAS can override this computed default. RUN EXTRAS="${MASKANX_PIP_EXTRAS}"; \ if [ -z "$EXTRAS" ]; then \ case "$MASKANX_VARIANT" in \ core) EXTRAS="[local]" ;; \ browser) EXTRAS="[browser,local]" ;; \ full) EXTRAS="[all,local]" ;; \ *) EXTRAS="[all,local]" ;; \ esac; \ fi; \ echo ">>> Installing MaskanX with extras=${EXTRAS} (variant=${MASKANX_VARIANT})" && \ pip install --no-cache-dir torch --index-url https://download.pytorch.org/whl/cpu && \ pip install --no-cache-dir ".${EXTRAS}" # Preload the default local embedding model at build time so first production # memory queries don't stall while downloading from Hugging Face. RUN mkdir -p /app/model-cache \ && if [ "$MASKANX_PRELOAD_EMBEDDINGS" = "1" ]; then \ python -c "from sentence_transformers import SentenceTransformer; SentenceTransformer('all-MiniLM-L6-v2')" ; \ else \ echo ">>> Skipping embedding model preload"; \ fi # Non-root user for running the app (supervisord stays root for system services). RUN groupadd -r maskanx && useradd -r -g maskanx -m -s /bin/bash maskanx \ && mkdir -p /app/working /app/working.secret /app/logs /home/maskanx/.config/pinchtab /app/model-cache \ && chown -R maskanx:maskanx /app/working /app/working.secret /app/logs /home/maskanx/.config /app/model-cache # Config.json is generated at runtime by entrypoint.sh (only if missing), # so it persists user settings across container restarts. # MaskanX app port (default 8088). Override at runtime with -e MASKANX_PORT=3000. ENV ADCLAW_PORT=8088 COPY deploy/config/supervisord.conf.template /etc/supervisor/conf.d/supervisord.conf.template COPY deploy/config/supervisord.browser.conf.template /etc/supervisor/conf.d/supervisord.browser.conf.template COPY deploy/entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh EXPOSE 8088 CMD ["/entrypoint.sh"]