Spaces:
Sleeping
Sleeping
| # HermesFace on Hugging Face Spaces β Source build | |
| # Builds Hermes Agent from source since no pre-built Docker image is published | |
| # Rebuild 2026-04-13: initial release | |
| # ββ Stage 1: Build Hermes Agent from source ββββββββββββββββββββββββββββββ | |
| FROM ghcr.io/astral-sh/uv:0.11-python3.13-trixie AS uv_source | |
| FROM tianon/gosu:1.19-trixie AS gosu_source | |
| FROM node:22-trixie-slim AS node_source | |
| FROM python:3.13-slim-trixie | |
| SHELL ["/bin/bash", "-c"] | |
| ENV PYTHONUNBUFFERED=1 | |
| ENV PLAYWRIGHT_BROWSERS_PATH=/opt/hermes/.playwright | |
| # ββ System dependencies ββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| RUN echo "[build] Installing system deps..." && START=$(date +%s) \ | |
| && apt-get update \ | |
| && apt-get install -y --no-install-recommends \ | |
| build-essential \ | |
| ripgrep ffmpeg gcc python3-dev libffi-dev procps \ | |
| git ca-certificates curl \ | |
| && rm -rf /var/lib/apt/lists/* \ | |
| && echo "[build] System deps: $(($(date +%s) - START))s" | |
| # ββ Non-root user ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| RUN useradd -u 10000 -m -d /opt/data hermes | |
| COPY --chmod=0755 --from=gosu_source /gosu /usr/local/bin/ | |
| COPY --chmod=0755 --from=uv_source /usr/local/bin/uv /usr/local/bin/uvx /usr/local/bin/ | |
| COPY --chmod=0755 --from=node_source /usr/local/bin/node /usr/local/bin/node | |
| COPY --from=node_source /usr/local/lib/node_modules /usr/local/lib/node_modules | |
| RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \ | |
| && ln -s /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx \ | |
| && [[ "$(python --version 2>&1)" == "Python 3.13."* ]] \ | |
| && [[ "$(node --version)" == v22.* ]] | |
| # ββ Clone and build Hermes Agent (P1-T01 pinable upstream) ββββββββββββββ | |
| ARG HERMES_UPSTREAM_REPO=https://github.com/NousResearch/hermes-agent.git | |
| ARG HERMES_UPSTREAM_REF=8fc278207b0f5b25e567966f9615e1b1737f62af | |
| RUN [[ "${HERMES_UPSTREAM_REF}" =~ ^[0-9a-fA-F]{40}$ ]] \ | |
| || { echo "HERMES_UPSTREAM_REF must be an exact 40-character commit SHA" >&2; exit 2; } \ | |
| && echo "[build] Fetching Hermes Agent commit ${HERMES_UPSTREAM_REF}..." && START=$(date +%s) \ | |
| && git init /opt/hermes \ | |
| && cd /opt/hermes \ | |
| && git remote add origin "${HERMES_UPSTREAM_REPO}" \ | |
| && git fetch --depth 1 origin "${HERMES_UPSTREAM_REF}" \ | |
| && git checkout --detach FETCH_HEAD \ | |
| && test "$(git rev-parse HEAD)" = "${HERMES_UPSTREAM_REF}" \ | |
| && printf '%s\n' "${HERMES_UPSTREAM_REF}" > /opt/hermes/HERMES_UPSTREAM_COMMIT \ | |
| && echo "[build] Verified upstream HEAD=$(git rev-parse HEAD)" \ | |
| && echo "[build] Fetch: $(($(date +%s) - START))s" | |
| COPY scripts/verify_upstream_integration.py /tmp/verify_upstream_integration.py | |
| RUN python /tmp/verify_upstream_integration.py /opt/hermes | |
| WORKDIR /opt/hermes | |
| # ββ Node dependencies + Playwright + Web Dashboard build βββββββββββββββββ | |
| RUN echo "[build] Installing Node deps + Playwright..." && START=$(date +%s) \ | |
| && test -f /opt/hermes/package-lock.json \ | |
| && npm ci --prefer-offline --no-audit \ | |
| && npx --yes playwright@1.52.0 install chromium --only-shell \ | |
| && if [ -f /opt/hermes/scripts/whatsapp-bridge/package.json ]; then \ | |
| test -f /opt/hermes/scripts/whatsapp-bridge/package-lock.json; \ | |
| cd /opt/hermes/scripts/whatsapp-bridge && npm ci --prefer-offline --no-audit; \ | |
| fi \ | |
| && echo "[build] Building web dashboard..." \ | |
| && cd /opt/hermes/web && npm run build \ | |
| && cd /opt/hermes && npm cache clean --force \ | |
| && echo "[build] Node deps + web dashboard: $(($(date +%s) - START))s" | |
| # ββ Python dependencies ββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| COPY --chown=hermes:hermes requirements.lock /tmp/hermesface-requirements.lock | |
| RUN chown -R hermes:hermes /opt/hermes | |
| USER hermes | |
| RUN echo "[build] Installing Python deps..." && START=$(date +%s) \ | |
| && cd /opt/hermes \ | |
| && test -f uv.lock \ | |
| && uv sync --frozen --all-extras \ | |
| && uv pip install --no-cache-dir -r /tmp/hermesface-requirements.lock \ | |
| && echo "[build] Python deps: $(($(date +%s) - START))s" | |
| USER root | |
| RUN chmod +x /opt/hermes/docker/entrypoint.sh | |
| # ββ Prepare runtime dirs ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| RUN mkdir -p /opt/data/cron /opt/data/sessions /opt/data/logs /opt/data/hooks \ | |
| /opt/data/memories /opt/data/skills /opt/data/skins /opt/data/plans \ | |
| /opt/data/workspace /opt/data/home \ | |
| && chown -R hermes:hermes /opt/data | |
| USER hermes | |
| # ββ HermesFace scripts (persistence + entrypoint + DNS + assets) ββββββ | |
| ARG CACHE_BUST=2026-07-20-futures-v1 | |
| RUN echo "Build: ${CACHE_BUST}" | |
| COPY --chown=hermes:hermes scripts /opt/data/scripts | |
| COPY --chown=hermes:hermes assets /opt/data/assets | |
| COPY --chown=hermes:hermes hermes_overlay /opt/data/hermes_overlay | |
| COPY --chown=hermes:hermes hermes_overlay /opt/hermesface_overlay | |
| RUN chmod +x /opt/data/scripts/entrypoint.sh \ | |
| /opt/data/scripts/dns-resolve.py \ | |
| /opt/data/scripts/hermes_persist.py \ | |
| /opt/data/scripts/save_to_dataset.py \ | |
| /opt/data/scripts/save_to_dataset_atomic.py \ | |
| /opt/data/scripts/restore_from_dataset.py \ | |
| /opt/data/scripts/restore_from_dataset_atomic.py | |
| ENV HERMES_HOME=/opt/data | |
| ENV PATH="/opt/hermes/.venv/bin:$PATH" | |
| WORKDIR /opt/data | |
| CMD ["/opt/data/scripts/entrypoint.sh"] | |