Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,18 +183,31 @@ npm install
npm run dev # default :8080
```

Or with Docker:
Or with Docker (API + MCP):

```bash
docker compose up --build -d
```

Optional: include the dashboard service profile:

```bash
docker compose --profile ui up --build -d
```

Check service status:

```bash
docker compose ps
curl -f http://localhost:8080/health
```

The backend exposes:

- `/api/memory/*` – memory operations
- `/api/temporal/*` – temporal knowledge graph
- `/mcp` – MCP server
- dashboard UI
- dashboard UI (when `ui` profile is enabled)

---

Expand Down Expand Up @@ -552,4 +565,4 @@ Issues and PRs are welcome.

## 13. License

OpenMemory is licensed under **Apache 2.0**. See [LICENSE](LICENSE) for details.
OpenMemory is licensed under **Apache 2.0**. See [LICENSE](LICENSE) for details.
12 changes: 9 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '3.8'

services:
openmemory:
build:
Expand Down Expand Up @@ -122,14 +120,22 @@ services:
- openmemory_data:/data
restart: unless-stopped
healthcheck:
test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://localhost:8080/health']
test:
[
'CMD',
'node',
'-e',
'require("http").get("http://localhost:8080/health",(res)=>process.exit(res.statusCode===200?0:1)).on("error",()=>process.exit(1))',
]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s

# Dashboard: Web UI for visualizing and managing memories
dashboard:
profiles:
- ui
build:
context: ./dashboard
dockerfile: Dockerfile
Expand Down
36 changes: 9 additions & 27 deletions packages/openmemory-js/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,49 +1,31 @@
# ===== BUILD STAGE =====
FROM node:20-alpine AS builder
FROM node:20-bookworm-slim AS builder

WORKDIR /app

# Install system dependencies required for native module compilation,
# plus curl and bash (needed to run the Bun installation script)
RUN apk add --no-cache python3 make g++ curl bash

# Install Bun globally and relocate it to a shared, persistent location
RUN curl -fsSL https://bun.sh/install | bash \
&& mv /root/.bun /opt/bun \
&& ln -s /opt/bun/bin/bun /usr/local/bin/bun

# Ensure Bun is available in PATH for subsequent commands
ENV PATH="/opt/bun/bin:${PATH}"

# Copy package manifests to install dependencies
COPY package*.json ./

# Install all dependencies (including devDependencies) using Bun
# --frozen-lockfile ensures reproducible builds
# --concurrent-scripts and --network-concurrency optimize install speed
RUN bun install --frozen-lockfile
# Install all dependencies (including devDependencies) for build
RUN npm ci

# Copy source code and build the application
COPY src/ ./src/
COPY tsconfig.json ./
RUN bun run build
RUN NODE_OPTIONS="--max-old-space-size=4096" npm run build

# Remove devDependencies to reduce image size
# (Removing all the devDependencies that we dont need in the final build)
# Remove devDependencies to reduce image size for the runtime image
RUN npm prune --omit=dev


# ===== PRODUCTION STAGE =====
FROM node:20-alpine AS production
FROM node:20-bookworm-slim AS production

WORKDIR /app

# Install timezone data for proper TZ support
RUN apk add --no-cache tzdata

# Create a dedicated non-root user for security
RUN addgroup -g 1001 -S appgroup \
&& adduser -u 1001 -S appuser -G appgroup
RUN groupadd --gid 1001 appgroup \
&& useradd --uid 1001 --gid appgroup --system --no-create-home appuser

# Copy only production artifacts from the builder stage
COPY --from=builder /app/node_modules ./node_modules/
Expand All @@ -66,4 +48,4 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
CMD node -e "require('http').get('http://localhost:8080/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"

# Start the application using npm
ENTRYPOINT ["npm", "start"]
ENTRYPOINT ["npm", "start"]
Loading