After configuring your source database for PowerSync, you’ll need to setup your PowerSync Service.

This entails:

  1. Configuring sync bucket storage

  2. Defining your PowerSync config

    1. Defining connections to your source database, and sync bucket storage database

    2. Defining your Sync Rules

    3. Defining your auth method

Examples of the above can be found in our demo application here. Below we go through these in more detail.

Deploy PowerSync on Coolify: See our integration guide for deploying the PowerSync Service on Coolify. This can simplify the setup and management of the deployment.

Configure Sync Bucket Storage

The PowerSync Service requires a storage backend for sync buckets. You can use either MongoDB or Postgres for this purpose. The storage backend is separate from your source database.

MongoDB Storage

MongoDB requires at least one replica set node. A single node is fine for development/staging environments, but a 3-node replica set is recommended for production.

MongoDB Atlas enables replica sets by default for new clusters.

However, if you’re using your own environment you can enable this manually by running:

mongosh "mongodb+srv://powersync.abcdef.mongodb.net/" --apiVersion 1 --username myuser --eval 'try{rs.status().ok && quit(0)} catch {} rs.initiate({_id: "rs0", version: 1, members: [{ _id: 0, host : "mongo:27017" }]})'

If you are rolling your own Docker environment, you can include this init script in your docker-compose file to configure a replica set as once-off operation:

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

Postgres Storage (Beta)

Available since version 1.3.8 of journeyapps/powersync-service, you can use Postgres as an alternative storage backend for sync buckets. This feature is currently in beta.

Database Setup

You’ll need to create a dedicated user and schema for PowerSync storage. You can either:

  1. Let PowerSync create the schema (recommended):
CREATE USER powersync_storage_user WITH PASSWORD 'secure_password';
-- The user should only have access to the schema it created
GRANT CREATE ON DATABASE postgres TO powersync_storage_user;
  1. Or manually create the schema:
CREATE USER powersync_storage_user WITH PASSWORD 'secure_password';
CREATE SCHEMA IF NOT EXISTS powersync AUTHORIZATION powersync_storage_user;
GRANT CONNECT ON DATABASE postgres TO powersync_storage_user;
GRANT USAGE ON SCHEMA powersync TO powersync_storage_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA powersync TO powersync_storage_user;

Demo app: A demo app with Postgres bucket storage is available here.

PowerSync Configuration

The PowerSync Service is configured using key/value pairs in a config file, and supports the following configuration methods:

  1. Inject config as an environment variable (which contains the base64 encoding of a config file)

  2. Use a config file mounted on a volume

  3. Specify the config as a command line parameter (again base64 encoded)

Both YAML and JSON config files are supported, and you can see examples of the above configuration methods in our demo app’s docker-compose file.

A detailed config.yaml example with additional comments can be found here:

self-host-demo/config/powersync.yaml at main · powersync-ja/self-host-demoGitHub

The config file schema is also available here:

self-host-demo/schema/schema.json at main · powersync-ja/self-host-demoGitHub

Below is a skeleton config file you can copy and paste to edit locally:

# config.yaml

# Settings for source database replication
replication:
  # Specify database connection details
  # Note only 1 connection is currently supported
  # Multiple connection support is on the roadmap
  connections:
    - type: postgresql
      # The PowerSync server container can access the Postgres DB via the DB's service name.
      # In this case the hostname is pg-db

      # The connection URI or individual parameters can be specified.
      uri: postgresql://postgres:mypassword@pg-db:5432/postgres

      # SSL settings
      sslmode: disable # 'verify-full' (default) or 'verify-ca' or 'disable'
      # Note: 'disable' is only suitable for local/private networks, not for public networks

# Connection settings for sync bucket storage (MongoDB and Postgres are supported)
storage:
  # Option 1: MongoDB Storage
  type: mongodb
  uri: mongodb://mongo:27017/powersync_demo
  # Use these if authentication is required. The user should have `readWrite` and `dbAdmin` roles
  # username: myuser
  # password: mypassword

  # Option 2: Postgres Storage
  # type: postgresql
  # This accepts the same parameters as a Postgres replication source connection
  # uri: postgresql://powersync_storage_user:secure_password@storage-db:5432/postgres
  # sslmode: disable

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

# Specify sync rules
sync_rules:
  content: |
    bucket_definitions:
      global:
        data:
          - SELECT * FROM lists
          - SELECT * FROM todos

# Settings for client authentication
client_auth:
  # Enable this if using Supabase Auth
  # supabase: true
  # supabase_jwt_secret: your-secret

  # JWKS URIs can be specified here.
  jwks_uri: http://demo-backend:6060/api/auth/keys

  # JWKS audience
  audience: ['powersync-dev', 'powersync']

  # Settings for telemetry reporting
  # See https://docs.powersync.com/self-hosting/telemetry
  telemetry:
    # Opt out of reporting anonymized usage metrics to PowerSync telemetry service
    disable_telemetry_sharing: false

Specify the connection to Postgres in the replication section. Retrieving your database connection string / individual parameters differs by database hosting provider. See Database Connection for further details.

If you are using hosted Supabase, you will need to enable IPv6 for Docker as per https://docs.docker.com/config/daemon/ipv6/

If your host OS does not support Docker IPv6 e.g. macOS, you will need to run Supabase locally.

This is because Supabase only allows direct database connections over IPv6 — PowerSync cannot connect using the connection pooler.

Specify the connection to your sync bucket storage provider (Postgres or MongoDB) in the storage section.

Postgres Storage

Separate Postgres servers are required for replication connections and sync bucket storage if using Postgres versions below 14.

Postgres VersionServer configuration
Below 14Separate servers are required for the source and sync bucket storage. Replication will be blocked if the same server is detected.
14 and aboveThe source database and sync bucket storage database can be on the same server. Using the same database (with separate schemas) is supported but may lead to higher CPU usage. Using separate servers remains an option.

Environment Variables

The config file uses custom tags for environment variable substitution.

Using !env [variable name] will substitute the value of the environment variable named [variable name].

Only environment variables with names starting with PS_ can be substituted.

See examples here:

self-host-demo/config/powersync.yaml at main · powersync-ja/self-host-demoGitHub

Sync Rules

Your project’s sync rules can either be specified within your configuration file directly, or in a separate file that is referenced.

# config.yaml

# Define sync rules:
sync_rules:
  content: |
    bucket_definitions:
      global:
        data:
          - SELECT * FROM lists
          - SELECT * FROM todos

# Alternatively, reference a sync rules file
# sync_rules:
  # path: sync_rules.yaml

We recommend starting with syncing a single table in a global bucket. Choose a table and sync it by adding the following to your sync rules:

sync_rules:
  content: |
    bucket_definitions:
      global:
        data:
          # Sync all mytable
          - SELECT * FROM mytable

For more information about sync rules see:

Sync Rules

Checkpoint

To verify that your sync rules are functioning correctly, inspect the contents of your sync bucket in MongoDB.

If you are running MongoDB in Docker, run the following:

docker exec -it {MongoDB container name} mongosh "mongodb://{MongoDB service host}/{MongoDB database name}" --eval "db.bucket_data.find().pretty()"
# Example
docker exec -it self-host-demo-mongo-1 mongosh "mongodb://localhost:27017/powersync_demo" --eval "db.bucket_data.find().pretty()"