FROM node:22 # Install dependencies for Puppeteer to run headlessly RUN apt-get update && apt-get install -y \ ca-certificates \ fonts-liberation \ libappindicator3-1 \ libasound2 \ libatk-bridge2.0-0 \ libatk1.0-0 \ libc6 \ libcairo2 \ libcups2 \ libdbus-1-3 \ libexpat1 \ libfontconfig1 \ libgbm1 \ libgcc1 \ libglib2.0-0 \ libgtk-3-0 \ libnspr4 \ libnss3 \ libpango-1.0-0 \ libpangocairo-1.0-0 \ libstdc++6 \ libx11-6 \ libx11-xcb1 \ libxcb1 \ libxcomposite1 \ libxcursor1 \ libxdamage1 \ libxext6 \ libxfixes3 \ libxi6 \ libxrandr2 \ libxrender1 \ libxss1 \ libxtst6 \ lsb-release \ curl \ xdg-utils \ python3 \ python3-venv \ python3-pip \ git \ sudo \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # Create an unprivileged user for the Browser Agent to run in isolation RUN useradd -m -s /bin/bash agent_runner # Allow the node user (UID 1000, default HF user) to sudo as agent_runner without password RUN echo "node ALL=(agent_runner) NOPASSWD: ALL" >> /etc/sudoers # --- IServ filter: removes person, place and school names from IServ tasks (iserv-filter/, see src/api/iserv-filtered.js) # Own unprivileged user and venv. Its process gets only API_BEARER_TOKEN, never the IServ secrets (see start.sh). RUN useradd -m -s /bin/bash iserv_runner RUN echo "node ALL=(iserv_runner) NOPASSWD: ALL" >> /etc/sudoers COPY iserv-filter/requirements.txt /tmp/iserv-filter-requirements.txt RUN python3 -m venv /opt/filter-venv \ && /opt/filter-venv/bin/pip install --no-cache-dir --upgrade pip \ && /opt/filter-venv/bin/pip install --no-cache-dir torch==2.12.1+cpu --extra-index-url https://download.pytorch.org/whl/cpu \ && /opt/filter-venv/bin/pip install --no-cache-dir -r /tmp/iserv-filter-requirements.txt # Download and setup Piper TTS RUN mkdir -p piper_tts && \ curl -L https://github.com/rhasspy/piper/releases/download/2023.11.14-2/piper_linux_x86_64.tar.gz -o piper.tar.gz && \ tar -xzf piper.tar.gz -C piper_tts --strip-components=1 && \ rm piper.tar.gz && \ chmod +x piper_tts/piper && \ curl -L "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/de/de_DE/thorsten/high/de_DE-thorsten-high.onnx" -o piper_tts/de_DE-thorsten-high.onnx && \ curl -L "https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/de/de_DE/thorsten/high/de_DE-thorsten-high.onnx.json" -o piper_tts/de_DE-thorsten-high.onnx.json # --- Python & Browser-Agent Dependencies --- # Install uv (fast python package manager) globally via pip to ensure it's in PATH RUN pip3 install --break-system-packages uv # Install Node modules COPY package*.json ./ RUN npm install # Copy application source COPY . . # Build Vite App RUN npm run build # Setup Python environment for Browser Agent ENV PLAYWRIGHT_BROWSERS_PATH=/app/Browser_Agent/pw-browsers RUN cd Browser_Agent && uv venv && . .venv/bin/activate && uv pip install -e . && uv run playwright install chromium # Grant ownership of Browser_Agent to the isolated user RUN chown -R agent_runner:agent_runner /app/Browser_Agent # Copy start script RUN chmod +x /app/start.sh # Expose Hugging Face Space port (Node.js) EXPOSE 7860 # Start dual processes CMD ["/app/start.sh"]