Spaces:
Build error
Build error
| # ===== MULTI-STAGE DOCKERFILE FOR OPENHANDS WEBAPP ===== | |
| # This Dockerfile builds and runs the complete OpenHands application | |
| # including both the React frontend and Python FastAPI backend | |
| # ===== FRONTEND BUILD STAGE ===== | |
| FROM node:22.13.1-bookworm-slim AS frontend-builder | |
| WORKDIR /app/frontend | |
| # Copy package files first for better layer caching | |
| COPY frontend/package.json frontend/package-lock.json ./ | |
| # Install frontend dependencies | |
| RUN npm ci --only=production | |
| # Copy frontend source code | |
| COPY frontend/ ./ | |
| # Build the React application | |
| RUN npm run build | |
| # ===== BACKEND BUILD STAGE ===== | |
| FROM python:3.12.8-slim AS backend-builder | |
| WORKDIR /app | |
| # Set Poetry environment variables | |
| ENV POETRY_NO_INTERACTION=1 \ | |
| POETRY_VIRTUALENVS_IN_PROJECT=1 \ | |
| POETRY_VIRTUALENVS_CREATE=1 \ | |
| POETRY_CACHE_DIR=/tmp/poetry_cache | |
| # Install system dependencies for building Python packages | |
| RUN apt-get update -y \ | |
| && apt-get install -y --no-install-recommends \ | |
| curl \ | |
| make \ | |
| git \ | |
| build-essential \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Install Poetry | |
| RUN python3 -m pip install poetry==1.8.2 --break-system-packages | |
| # Copy Python dependency files first for better layer caching | |
| COPY pyproject.toml poetry.lock ./ | |
| RUN touch README.md | |
| # Install Python dependencies | |
| RUN poetry install --no-root --no-dev && rm -rf $POETRY_CACHE_DIR | |
| # ===== FINAL RUNTIME STAGE ===== | |
| FROM python:3.12.8-slim AS runtime | |
| WORKDIR /app | |
| # Build arguments | |
| ARG OPENHANDS_BUILD_VERSION=dev | |
| # Environment variables for OpenHands | |
| ENV RUN_AS_OPENHANDS=true \ | |
| OPENHANDS_USER_ID=42420 \ | |
| SANDBOX_LOCAL_RUNTIME_URL=http://host.docker.internal \ | |
| USE_HOST_NETWORK=false \ | |
| WORKSPACE_BASE=/opt/workspace_base \ | |
| OPENHANDS_BUILD_VERSION=$OPENHANDS_BUILD_VERSION \ | |
| SANDBOX_USER_ID=0 \ | |
| FILE_STORE=local \ | |
| FILE_STORE_PATH=/.openhands-state \ | |
| PYTHONPATH='/app' \ | |
| VIRTUAL_ENV=/app/.venv \ | |
| PATH="/app/.venv/bin:$PATH" | |
| # Create necessary directories | |
| RUN mkdir -p $FILE_STORE_PATH $WORKSPACE_BASE | |
| # Install runtime system dependencies | |
| RUN apt-get update -y \ | |
| && apt-get install -y --no-install-recommends \ | |
| curl \ | |
| ssh \ | |
| sudo \ | |
| git \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Configure user management for different UID ranges | |
| RUN sed -i 's/^UID_MIN.*/UID_MIN 499/' /etc/login.defs \ | |
| && sed -i 's/^UID_MAX.*/UID_MAX 1000000/' /etc/login.defs | |
| # Create app group and openhands user | |
| RUN groupadd app \ | |
| && useradd -l -m -u $OPENHANDS_USER_ID -s /bin/bash openhands \ | |
| && usermod -aG app openhands \ | |
| && usermod -aG sudo openhands \ | |
| && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers | |
| # Set ownership and permissions | |
| RUN chown -R openhands:app /app && chmod -R 770 /app \ | |
| && chown -R openhands:app $WORKSPACE_BASE && chmod -R 770 $WORKSPACE_BASE | |
| # Switch to openhands user for application setup | |
| USER openhands | |
| # Copy Python virtual environment from builder stage | |
| COPY --chown=openhands:app --chmod=770 --from=backend-builder /app/.venv /app/.venv | |
| # Copy Python application code | |
| COPY --chown=openhands:app --chmod=770 ./microagents ./microagents | |
| COPY --chown=openhands:app --chmod=770 ./openhands ./openhands | |
| COPY --chown=openhands:app --chmod=777 ./openhands/runtime/plugins ./openhands/runtime/plugins | |
| COPY --chown=openhands:app --chmod=770 ./openhands/agenthub ./openhands/agenthub | |
| # Copy configuration and metadata files | |
| COPY --chown=openhands:app ./pyproject.toml ./poetry.lock ./README.md ./MANIFEST.in ./LICENSE ./ | |
| # Download assets (run as openhands user to set correct ownership) | |
| RUN python openhands/core/download.py | |
| # Copy built frontend from frontend-builder stage | |
| COPY --chown=openhands:app --chmod=770 --from=frontend-builder /app/frontend/build ./frontend/build | |
| # Copy entrypoint script | |
| COPY --chown=openhands:app --chmod=770 ./containers/app/entrypoint.sh /app/entrypoint.sh | |
| # Ensure all files are in the app group | |
| RUN find /app \! -group app -exec chgrp app {} + 2>/dev/null || true | |
| # Switch back to root for entrypoint execution | |
| USER root | |
| # Health check to ensure the application is running | |
| HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ | |
| CMD curl -f http://localhost:3000/ || exit 1 | |
| # Expose the application port | |
| EXPOSE 3000 | |
| # Set entrypoint and default command | |
| ENTRYPOINT ["/app/entrypoint.sh"] | |
| CMD ["uvicorn", "openhands.server.listen:app", "--host", "0.0.0.0", "--port", "3000"] | |