Dockerfile 3.3 KB

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