Spaces:
Paused
Paused
File size: 7,487 Bytes
5ec8557 0b25cc0 5ec8557 0b25cc0 5ec8557 f8a7f2f 5ec8557 f8a7f2f 5ec8557 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | # mem0 Self-Hosted - Dockerfile
# Multi-stage build for mem0 self-hosted on HF Spaces
# Stage 1: Build mem0 API and Dashboard
# Stage 2: Runtime with PostgreSQL, supervisord, nginx
# =============================================================================
# Stage 1: Build mem0 API (Python)
# =============================================================================
FROM python:3.12-slim-bookworm AS api-builder
WORKDIR /build/api
# Install system dependencies for building
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
git \
curl \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Copy mem0 server source and root requirements
COPY server/ /build/api/
COPY requirements.txt /build/api/requirements.txt
# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt
# =============================================================================
# Stage 2: Build Dashboard (Next.js)
# =============================================================================
FROM node:20-alpine AS dashboard-builder
WORKDIR /build/dashboard
# Copy dashboard config files (package.json, next.config, tailwind, etc.)
COPY server/dashboard/ /build/dashboard/
# Fetch dashboard source from upstream mem0 repo (sparse clone of src/ and public/)
RUN apk add --no-cache git \
&& git clone --depth 1 --filter=blob:none --sparse \
https://github.com/mem0ai/mem0.git /tmp/mem0src \
&& cd /tmp/mem0src && git sparse-checkout set server/dashboard/src server/dashboard/public \
&& rm -rf /build/dashboard/src && cp -r /tmp/mem0src/server/dashboard/src /build/dashboard/src \
&& (cp -r /tmp/mem0src/server/dashboard/public /build/dashboard/public 2>/dev/null || mkdir -p /build/dashboard/public) \
&& rm -rf /tmp/mem0src
# Install dependencies
RUN npm install --no-audit --legacy-peer-deps
# Build Next.js standalone output - NEXT_PUBLIC_API_URL must be set at build time
ENV NEXT_TELEMETRY_DISABLED=1
ENV NEXT_PUBLIC_API_URL=/api
RUN npm run build
# NOTE: MEM0_LLM_* and MEM0_EMBEDDER_* are set in the runtime stage below
# Fix upstream bug: .env.http://localhost:7860/api is not a valid JS identifier
# Affects both server chunks (process.env.) and minified client bundles (s.env.)
# Server-side: replace with literal internal API URL
# Client-side: restore to NEXT_PUBLIC_API_URL with hardcoded fallback
RUN find /build/dashboard/.next -name '*.js' -exec \
sed -i 's|process\.env\.http://localhost:7860/api|"http://localhost:8000"|g' {} + 2>/dev/null || true && \
find /build/dashboard/.next -name '*.js' -exec \
sed -i 's|\.env\.http://localhost:7860/api|.env.NEXT_PUBLIC_API_URL||\"http://localhost:7860/api\"|g' {} + 2>/dev/null || true
# NOTE: Do NOT rewrite client PUT/DELETE on /api/auth/refresh to POST.
# Upstream contract (correct): PUT stores refresh_token cookie, POST rotates it,
# DELETE clears it. nginx routes /api/auth/refresh to the Next.js dashboard
# (see nginx.conf), which owns the httpOnly cookie — not to FastAPI.'
# =============================================================================
# Stage 3: Runtime - python:3.12-slim-bookworm with PostgreSQL, supervisord, nginx
# Pinned to bookworm so glibc matches api-builder exactly
# =============================================================================
FROM python:3.12-slim-bookworm
SHELL ["/bin/bash", "-c"]
# Environment variables
ENV PYTHONUNBUFFERED=1
ENV DEBIAN_FRONTEND=noninteractive
ENV PGDATA=/data/pgdata
ENV PGPORT=5432
# Default LLM/Embedder config — baked in so Space works without manual /api/configure
# Override via HF Space Secrets if needed
ENV MEM0_LLM_PROVIDER=openai
ENV MEM0_LLM_MODEL=memory-hub
ENV MEM0_LLM_API_KEY=sk-fc73b173f8a45ee0-e5chee-3b30445a
ENV MEM0_LLM_BASE_URL=https://deironk-9router.hf.space/v1
ENV MEM0_LLM_MAX_TOKENS=4000
ENV MEM0_LLM_TEMPERATURE=0.2
ENV MEM0_EMBEDDER_PROVIDER=openai
ENV MEM0_EMBEDDER_MODEL=gemini/gemini-embedding-001
ENV MEM0_EMBEDDER_API_KEY=sk-fc73b173f8a45ee0-e5chee-3b30445a
ENV MEM0_EMBEDDER_BASE_URL=https://deironk-9router.hf.space/v1
ENV MEM0_EMBEDDER_DIMS=1536
# Add PGDG apt repository for PostgreSQL 15 + pgvector
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates gnupg \
&& curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /usr/share/keyrings/postgresql.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" \
> /etc/apt/sources.list.d/pgdg.list \
&& rm -rf /var/lib/apt/lists/*
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
# PostgreSQL 15 + pgvector (from PGDG)
postgresql-15 \
postgresql-15-pgvector \
postgresql-client-15 \
# Node.js for dashboard runtime
nodejs \
npm \
# Process management
supervisor \
# Web server
nginx \
# Utilities
curl \
ca-certificates \
gosu \
procps \
vim \
nano \
htop \
bash \
git \
git-lfs \
gettext-base \
openssh-client \
tar \
gzip \
xz-utils \
bzip2 \
rsync \
&& rm -rf /var/lib/apt/lists/*
# Create UID 1000 user for HF Spaces FUSE compatibility
RUN useradd -u 1000 -m -d /opt/data mem0 && \
mkdir -p /opt/data/{pgdata,sessions,logs,history} && \
chown -R 1000:1000 /opt/data
# Copy built API from builder stage (python:3.12-slim base means Python runtime is already present)
COPY --from=api-builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=api-builder /usr/local/bin/uvicorn /usr/local/bin/uvicorn
COPY --from=api-builder /build/api /opt/mem0/api
# Copy built Dashboard from builder stage
# dashboard/entrypoint.sh does `cd /app`, so deploy there
COPY --from=dashboard-builder /build/dashboard/.next/standalone /app
COPY --from=dashboard-builder /build/dashboard/.next/static /app/.next/static
COPY --from=dashboard-builder /build/dashboard/public /app/public
COPY --from=dashboard-builder /build/dashboard/entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh && \
chown -R 1000:1000 /app
# Keep /opt/mem0/dashboard as a symlink for compatibility
RUN ln -s /app /opt/mem0/dashboard
# Copy configuration files
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY nginx.conf /etc/nginx/nginx.conf
COPY nginx-proxy.conf /etc/nginx/proxy.conf
COPY entrypoint.sh /entrypoint.sh
COPY init-db.sh /init-db.sh
COPY postgres-fuse-wrap /usr/local/bin/postgres-fuse-wrap
RUN chmod +x /entrypoint.sh /init-db.sh /usr/local/bin/postgres-fuse-wrap
# Create runtime directories writable by mem0 (UID 1000)
RUN mkdir -p /var/log/nginx /var/cache/nginx /run/nginx \
/var/log/supervisor /run/supervisor /var/run/postgresql \
/var/lib/nginx/body /var/lib/nginx/fastcgi \
/var/lib/nginx/proxy /var/lib/nginx/scgi /var/lib/nginx/uwsgi \
/app && \
chown -R 1000:1000 /var/log/nginx /var/cache/nginx /run/nginx \
/var/log/supervisor /run/supervisor /var/run/postgresql \
/var/lib/nginx
# Expose HF Spaces port
EXPOSE 7860
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:7860/health || exit 1
# Run as root for initialization, then drop to UID 1000
ENTRYPOINT ["/entrypoint.sh"] |