Docker Deployment Guide for PowerMem Server

July 8, 2026 ยท View on GitHub

This guide provides instructions for building and running PowerMem Server using Docker.

Table of Contents

Prerequisites

  • Docker 20.10 or later
  • Docker Compose 2.0 or later (optional, for Compose setup)
  • A project-root .env file for single-container deployment. Start with cp .env.example .env, then set the LLM provider, model, API key, and base URL required by your provider. For Docker Compose, copy the same settings to docker/.env.

Quick Start

Build and Run

# Build the Docker image (from project root)
docker build -t oceanbase/powermem-server:latest -f docker/Dockerfile .

# Run the container with shared .env file (recommended)
# This allows both SDK and Server to use the same configuration
docker run -d \
  --name powermem-server \
  -p 8848:8848 \
  -v $(pwd)/.env:/app/.env:ro \
  --env-file .env \
  oceanbase/powermem-server:latest

The server will be available at http://localhost:8848.

Note: If you have a .env file that's shared between the SDK and Server, use the first command with volume mount (-v) to ensure both components read from the same configuration file. See Shared .env File for more details.

Using Docker Compose

The docker/docker-compose.yml file is the recommended local stack when you want PowerMem Server and a bundled seekdb database to start together. Prepare docker/.env before starting the stack:

cp .env.example docker/.env
# Edit docker/.env with your LLM provider, model, API key, and base URL.

It is pre-configured to:

  • Load environment variables from docker/.env
  • Reuse the same LLM, embedding, server, and other application settings through container environment variables
  • Connect powermem-server to the seekdb service on the internal Compose network
# Start PowerMem Server and seekdb (from project root)
docker compose -f docker/docker-compose.yml up -d --build

# View logs
docker compose -f docker/docker-compose.yml logs -f

# Stop the server
docker compose -f docker/docker-compose.yml down

Note: The Docker Compose setup intentionally overrides DATABASE_PROVIDER and OCEANBASE_* so the server uses the bundled seekdb container. If your .env points to an existing database service, use the single-container deployment or a custom Compose override instead.

Building the Docker Image

Basic Build

# Build from project root directory
docker build -t oceanbase/powermem-server:latest -f docker/Dockerfile .

Build with Custom Tag

# Build from project root directory
docker build -t oceanbase/powermem-server:v0.2.1 -f docker/Dockerfile .

Build with Mirror Sources (for slow network)

If you're experiencing slow download speeds or network timeouts, you can use mirror sources for both pip and apt-get:

# Using Tsinghua mirror (China) - speeds up both pip and apt-get
docker build -t oceanbase/powermem-server:latest -f docker/Dockerfile \
  --build-arg PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \
  --build-arg PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn \
  --build-arg DEBIAN_MIRROR=mirrors.tuna.tsinghua.edu.cn .

# Using Aliyun mirror (China) - speeds up both pip and apt-get
docker build -t oceanbase/powermem-server:latest -f docker/Dockerfile \
  --build-arg PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple \
  --build-arg PIP_TRUSTED_HOST=mirrors.aliyun.com \
  --build-arg DEBIAN_MIRROR=mirrors.aliyun.com .

# Using only pip mirror (if apt-get is fast enough)
docker build -t oceanbase/powermem-server:latest -f docker/Dockerfile \
  --build-arg PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \
  --build-arg PIP_TRUSTED_HOST=pypi.tuna.tsinghua.edu.cn .

# Using only Debian mirror (if pip is fast enough)
docker build -t oceanbase/powermem-server:latest -f docker/Dockerfile \
  --build-arg DEBIAN_MIRROR=mirrors.aliyun.com .

Note:

  • The Dockerfile has been configured with a longer timeout (300 seconds) for pip to handle slow network connections.
  • Using Debian mirror can significantly speed up apt-get operations (especially when installing gcc, g++, etc.).
  • The docker-build-mirror Makefile target automatically configures both pip and Debian mirrors.

Build Arguments (if needed in future)

Currently, the Dockerfile uses a multi-stage build to optimize image size. The build process:

  1. Builder stage: Installs all dependencies and builds the package
  2. Final stage: Creates a minimal runtime image with only necessary files

Running the Container

Basic Run

docker run -d \
  --name powermem-server \
  -p 8848:8848 \
  oceanbase/powermem-server:latest

Run with Environment Variables

docker run -d \
  --name powermem-server \
  -p 8848:8848 \
  -e POWERMEM_SERVER_HOST=0.0.0.0 \
  -e POWERMEM_SERVER_PORT=8848 \
  -e POWERMEM_SERVER_WORKERS=4 \
  -e POWERMEM_SERVER_API_KEYS=key1,key2,key3 \
  -e POWERMEM_SERVER_AUTH_ENABLED=true \
  -e POWERMEM_SERVER_LOG_LEVEL=INFO \
  oceanbase/powermem-server:latest

Run with Environment File

Create a .env file:

POWERMEM_SERVER_HOST=0.0.0.0
POWERMEM_SERVER_PORT=8848
POWERMEM_SERVER_WORKERS=4
POWERMEM_SERVER_API_KEYS=your-api-key-1,your-api-key-2
POWERMEM_SERVER_AUTH_ENABLED=true
POWERMEM_SERVER_LOG_LEVEL=INFO
POWERMEM_SERVER_CORS_ENABLED=true
POWERMEM_SERVER_CORS_ORIGINS=*

Run with the environment file:

docker run -d \
  --name powermem-server \
  -p 8848:8848 \
  --env-file .env \
  oceanbase/powermem-server:latest

Run with Shared .env File (SDK and Server)

When both the SDK and Server need to use the same .env file, you can mount it as a volume. This allows the Server running in Docker to read the same configuration file that the SDK uses locally:

docker run -d \
  --name powermem-server \
  -p 8848:8848 \
  -v $(pwd)/.env:/app/.env:ro \
  --env-file .env \
  oceanbase/powermem-server:latest

Note: The --env-file flag loads environment variables from .env into the container's environment, while the volume mount (-v) makes the .env file accessible inside the container at /app/.env so the Server's configuration loader can read it directly. This ensures both SDK and Server use the exact same configuration values.

Benefits of this approach:

  • Single source of truth: One .env file for both SDK and Server
  • Consistent configuration: Both components read from the same file
  • Easy updates: Modify .env once, both components pick up changes (after container restart)

Run with Volume Mounts (for persistent data)

If you need to mount volumes for logs or configuration:

docker run -d \
  --name powermem-server \
  -p 8848:8848 \
  -v ./logs:/app/logs \
  -v ./config:/app/config \
  --env-file .env \
  oceanbase/powermem-server:latest

Configuration

Shared .env File for SDK and Server

PowerMem Server and SDK are designed to share the same .env file. The .env file contains configuration for both:

  • Server configuration: POWERMEM_SERVER_*, POWERMEM_AUTH_*, POWERMEM_RATE_LIMIT_*, etc.
  • SDK configuration: DATABASE_PROVIDER, OCEANBASE_*, POSTGRES_*, LLM_*, EMBEDDING_*, etc.

When running the Server in Docker, you have two options:

Mount the .env file as a read-only volume so the Server can read it directly:

docker run -d \
  --name powermem-server \
  -p 8848:8848 \
  -v $(pwd)/.env:/app/.env:ro \
  --env-file .env \
  oceanbase/powermem-server:latest

This approach:

  • Allows the Server to read .env file directly (same as SDK)
  • Ensures both SDK and Server use identical configuration
  • Makes it easy to update configuration by editing the .env file

Option 2: Environment Variables Only

If you prefer not to mount the file, you can use --env-file to load environment variables:

docker run -d \
  --name powermem-server \
  -p 8848:8848 \
  --env-file .env \
  oceanbase/powermem-server:latest

Note: With Docker Compose, docker/.env is loaded through env_file. See the docker/docker-compose.yml file for details.

Environment Variables

The .env file contains configuration for both the PowerMem SDK and Server. The following sections describe the variables used by the Server. For SDK configuration variables (database, LLM, embedding providers), refer to the Configuration Guide.

Server Settings

VariableDefaultDescription
POWERMEM_SERVER_HOST0.0.0.0Host to bind the server to
POWERMEM_SERVER_PORT8848Port to bind the server to
POWERMEM_SERVER_WORKERS4Number of worker processes
POWERMEM_SERVER_RELOADfalseEnable auto-reload (development only)

Authentication Settings

VariableDefaultDescription
POWERMEM_SERVER_AUTH_ENABLEDtrueEnable API key authentication
POWERMEM_SERVER_API_KEYS``Comma-separated list of API keys

Rate Limiting Settings

VariableDefaultDescription
POWERMEM_SERVER_RATE_LIMIT_ENABLEDtrueEnable rate limiting
POWERMEM_SERVER_RATE_LIMIT_PER_MINUTE100Requests per minute per IP

Logging Settings

VariableDefaultDescription
POWERMEM_SERVER_LOG_LEVELINFOLog level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
POWERMEM_SERVER_LOG_FORMATjsonLog format (json or text)

CORS Settings

VariableDefaultDescription
POWERMEM_SERVER_CORS_ENABLEDtrueEnable CORS
POWERMEM_SERVER_CORS_ORIGINS*Comma-separated list of allowed origins

API Settings

VariableDefaultDescription
POWERMEM_SERVER_API_TITLEPowerMem APIAPI title
POWERMEM_SERVER_API_VERSIONv1API version
POWERMEM_SERVER_API_DESCRIPTIONPowerMem HTTP API Server - Intelligent Memory SystemAPI description

SDK Configuration Variables (Shared with Server)

The following variables are used by the SDK but may also be referenced by the Server for database connections:

  • DATABASE_PROVIDER: Database provider (sqlite, oceanbase, postgres)
  • OCEANBASE_*: OceanBase database configuration
  • POSTGRES_*: PostgreSQL database configuration
  • SQLITE_*: SQLite database configuration
  • LLM_*: LLM provider configuration
  • EMBEDDING_*: Embedding provider configuration

For complete SDK configuration options, refer to the Configuration Guide.

Docker Compose

A docker/docker-compose.yml file is provided for easier deployment. The excerpt below shows the PowerMem Server service; the checked-in Compose file also includes a seekdb service that stores data in the docker_seekdb_data Docker volume and is wired to the server through OCEANBASE_HOST=seekdb.

version: '3.8'

services:
  powermem-server:
    build:
      context: ..
      dockerfile: docker/Dockerfile
    container_name: powermem-server
    ports:
      - "8848:8848"
    environment:
      - POWERMEM_SERVER_HOST=0.0.0.0
      - POWERMEM_SERVER_PORT=8848
      - POWERMEM_SERVER_WORKERS=4
      - POWERMEM_SERVER_API_KEYS=${POWERMEM_SERVER_API_KEYS:-}
      - POWERMEM_SERVER_AUTH_ENABLED=${POWERMEM_SERVER_AUTH_ENABLED:-true}
      - POWERMEM_SERVER_LOG_LEVEL=${POWERMEM_SERVER_LOG_LEVEL:-INFO}
      - POWERMEM_SERVER_CORS_ENABLED=${POWERMEM_SERVER_CORS_ENABLED:-true}
      - POWERMEM_DATABASE_URL=${POWERMEM_DATABASE_URL:-}
    env_file:
      - .env
    volumes:
      - ./logs:/app/logs
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8848/api/v1/system/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Using Docker Compose

# Start services (from project root)
docker compose -f docker/docker-compose.yml up -d --build

# View logs
docker compose -f docker/docker-compose.yml logs -f powermem-server

# Stop services
docker compose -f docker/docker-compose.yml down

# Rebuild and restart
docker compose -f docker/docker-compose.yml up -d --build

Production Deployment

Security Best Practices

  1. Use Secrets Management: Never hardcode API keys or passwords. Use Docker secrets or environment variable injection.

  2. Run as Non-Root User: The Docker image runs as a non-root user (powermem) by default.

  3. Network Security: Use Docker networks to isolate containers and restrict access.

  4. Resource Limits: Set appropriate resource limits:

docker run -d \
  --name powermem-server \
  --memory="2g" \
  --cpus="2" \
  -p 8848:8848 \
  oceanbase/powermem-server:latest
  1. Health Checks: The image includes a health check. Monitor container health:
docker ps  # Check STATUS column
docker inspect --format='{{.State.Health.Status}}' powermem-server

Production Docker Compose Example

services:
  powermem-server:
    build:
      context: ..
      dockerfile: docker/Dockerfile
    image: oceanbase/powermem-server:latest
    container_name: powermem-server
    restart: always
    ports:
      - "8848:8848"
    environment:
      - POWERMEM_SERVER_WORKERS=8
      - POWERMEM_SERVER_LOG_LEVEL=INFO
    env_file:
      - .env.production
    deploy:
      resources:
        limits:
          cpus: '4'
          memory: 4G
        reservations:
          cpus: '2'
          memory: 2G
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8848/api/v1/system/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Reverse Proxy Setup

For production, it's recommended to use a reverse proxy (nginx, traefik, etc.):

# nginx.conf example
upstream powermem {
    server powermem-server:8848;
}

server {
    listen 80;
    server_name api.powermem.example.com;

    location / {
        proxy_pass http://powermem;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Troubleshooting

Container Won't Start

  1. Check logs:
docker logs powermem-server
  1. Check environment variables:
docker exec powermem-server env | grep POWERMEM
  1. Check if .env file is mounted correctly:
# Check if .env file exists in container
docker exec powermem-server ls -la /app/.env

# View .env file contents (if mounted)
docker exec powermem-server cat /app/.env
  1. Verify database connection:
docker exec powermem-server python -c "import psycopg; psycopg.connect('${POWERMEM_DATABASE_URL}')"

Health Check Failing

  1. Check if server is running:
docker exec powermem-server curl -f http://localhost:8848/api/v1/system/health
  1. Check server logs:
docker logs powermem-server --tail 50

Port Already in Use

If port 8848 is already in use, change the port:

docker run -d \
  --name powermem-server \
  -p 8001:8848 \
  -e POWERMEM_SERVER_PORT=8848 \
  oceanbase/powermem-server:latest

Database Connection Issues

The entrypoint script waits up to 60 seconds for the database. If you need more time or want to disable the wait, you can modify the docker-entrypoint.sh script.

Permission Issues

The container runs as user powermem (UID 1000). If you mount volumes, ensure proper permissions:

sudo chown -R 1000:1000 ./logs

.env File Not Found or Not Readable

If the Server can't read the .env file:

  1. Verify the file is mounted:
docker exec powermem-server ls -la /app/.env
  1. Check file permissions:
# Ensure .env file is readable
chmod 644 .env
  1. Verify mount path:

    • The .env file should be mounted at /app/.env inside the container
    • Use -v $(pwd)/.env:/app/.env:ro to mount it as read-only
  2. Alternative: Use environment variables only: If mounting the file doesn't work, you can use --env-file to load variables:

docker run -d \
  --name powermem-server \
  -p 8848:8848 \
  --env-file .env \
  oceanbase/powermem-server:latest

Note: When using --env-file, the Server will read from environment variables, but the SDK running locally will still read from the .env file. This is fine as long as both have the same values.