| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- # ============================================================
- # LambdaAgentPaaS — Multi-stage Dockerfile
- #
- # Stage 1 (frontend): Node.js builds the React/Vite webui
- # Stage 2 (runtime): Python 3.12-slim runs the FastAPI server
- # with the built frontend baked in
- #
- # Data directory: /data (always mount this as a volume)
- # /data/agentpaas.db SQLite database
- # /data/instances/ Agent instance data
- # /data/knowledge_bases/ KB indexes
- # /data/logs/ Rotating application logs
- # ============================================================
- # ── Stage 1: Build frontend ───────────────────────────────
- FROM node:20-alpine AS frontend
- WORKDIR /build
- # Copy package files first for layer caching
- COPY webui/package.json webui/package-lock.json* webui/
- RUN cd webui && npm ci --prefer-offline
- # Copy full webui source
- COPY webui/ webui/
- # Build — vite.config.ts outputs to ../webui-dist (= /build/webui-dist)
- RUN cd webui && npm run build
- # ── Stage 2: Python runtime ──────────────────────────────
- FROM python:3.12-slim AS runtime
- WORKDIR /app
- # System dependencies (for PDF processing if used)
- RUN apt-get update && apt-get install -y --no-install-recommends \
- curl \
- && rm -rf /var/lib/apt/lists/*
- # Copy Python package manifests first (cache layer)
- COPY lambdagent/pyproject.toml lambdagent/
- COPY lambdagent_guard/pyproject.toml lambdagent_guard/
- COPY agentpaas/pyproject.toml agentpaas/
- # Install dependencies before copying full source (better caching)
- COPY lambdagent/ lambdagent/
- COPY lambdagent_guard/ lambdagent_guard/
- COPY agentpaas/ agentpaas/
- # Install Python packages
- # Use PyPI mirror configurable via build arg (for Chinese networks)
- ARG PIP_INDEX_URL=https://pypi.org/simple
- RUN pip install --no-cache-dir \
- -i ${PIP_INDEX_URL} \
- -e "lambdagent[all]" \
- -e "lambdagent_guard" \
- -e "agentpaas[all]" \
- pymupdf
- # Copy built frontend from Stage 1
- COPY --from=frontend /build/webui-dist /app/webui-dist
- # ── Runtime config ────────────────────────────────────────
- # All user data lives under /data — mount this as a volume
- ENV AGENTPAAS_DATA_DIR=/data
- ENV AGENTPAAS_HOST=0.0.0.0
- ENV AGENTPAAS_PORT=8000
- # /data is the single volume mount point for all persistent state
- VOLUME ["/data"]
- EXPOSE 8000
- # audit/AUDIT_2026-06-05.md #32: run as a non-root user. The container's
- # default UID would otherwise be 0; any RCE in the python process (or a
- # malicious agent template / pickle deserialization elsewhere) would get
- # root inside the container. UID 10001 dodges collision with common
- # host-mapped UIDs (0-9999 are typically already taken by host users).
- # /data and /app are chown'd so the runtime can still write logs +
- # instance state to the volume mount.
- RUN useradd --create-home --uid 10001 --shell /usr/sbin/nologin appuser \
- && mkdir -p /data \
- && chown -R appuser:appuser /data /app
- USER appuser
- HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
- CMD curl -sf http://localhost:8000/health || exit 1
- CMD ["python", "-m", "agentpaas", "serve", "--host", "0.0.0.0", "--port", "8000"]
|