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"] | |