Skip to main content
The easiest way to run PowerSync locally is with the PowerSync CLI, which scaffolds and manages a Docker Compose stack for you. See the Setup Guide for step-by-step CLI instructions: powersync init self-hosted + powersync docker configure + powersync docker start. If you’d prefer to write your own Docker Compose setup, here’s a minimal example.

Docker Compose Example

Create a working directory with three files:
powersync/
  docker-compose.yaml
  service.yaml
  sync-config.yaml

docker-compose.yaml

This example uses Postgres as the source database and MongoDB as bucket storage. Postgres is also supported as bucket storage — see Self-Hosted Instance Configuration for details.
services:
  powersync:
    restart: unless-stopped
    depends_on:
      mongo-rs-init:
        condition: service_completed_successfully
      postgres:
        condition: service_healthy
    image: journeyapps/powersync-service:latest
    command: ["start", "-r", "unified"]
    volumes:
      - ./service.yaml:/config/service.yaml
      - ./sync-config.yaml:/config/sync-config.yaml
    environment:
      POWERSYNC_CONFIG_PATH: /config/service.yaml
    ports:
      - 8080:8080

  # Source database (Postgres with logical replication enabled)
  postgres:
    image: postgres:latest
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_DB=postgres
      - POSTGRES_PASSWORD=postgres
      - PGPORT=5432
    volumes:
      - pg_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    command: ["postgres", "-c", "wal_level=logical"]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  # MongoDB used internally for bucket storage
  mongo:
    image: mongo:7.0
    command: --replSet rs0 --bind_ip_all --quiet
    restart: unless-stopped
    ports:
      - 27017:27017
    volumes:
      - mongo_storage:/data/db

  # Initializes the MongoDB replica set. This service will not usually be actively running  
  mongo-rs-init:
    image: mongo:7.0
    depends_on:
      - mongo
    restart: on-failure
    entrypoint:
      - bash
      - -c
      - 'mongosh --host mongo:27017 --eval ''try{rs.status().ok && quit(0)} catch {} rs.initiate({_id: "rs0", version: 1, members: [{ _id: 0, host : "mongo:27017" }]})'''

volumes:
  mongo_storage:
  pg_data:

service.yaml

The main PowerSync Service configuration. See Self-Hosted Instance Configuration for the full reference.
# Source database connection
replication:
  connections:
    - type: postgresql
      uri: postgresql://postgres:postgres@postgres:5432/postgres
      sslmode: disable  # verify-full, verify-ca, or disable

# Bucket storage (MongoDB shown; Postgres is also supported)
storage:
  type: mongodb
  uri: mongodb://mongo:27017/powersync_storage

# The port which the PowerSync API server will listen on
port: 8080

# Points to the sync config file
sync_config:
  path: sync-config.yaml

# Settings for client authentication
client_auth:
  # Enable this if using Supabase Auth
  supabase: false
  # Or enter a static collection of public keys for JWT verification, and generate a development token using the CLI (`powersync generate token`)
  # jwks:
  #   keys:
  #     - kty: 'RSA'
  #       n: '[rsa-modulus]'
  #       e: '[rsa-exponent]'
  #       alg: 'RS256'
  #       kid: '[key-id]'

  # JWKS audience
  # audience: ['powersync-dev', 'powersync', 'http://localhost:8080']

sync-config.yaml

Defines what data syncs to clients. See Sync Streams for full syntax.
config:
  edition: 3

streams:
  global:
    # Streams without parameters sync the same data to all users
    auto_subscribe: true
    queries:
      - SELECT * FROM todos
      - SELECT * FROM lists

Start the stack

docker compose up

Resources