{"id":38216009,"url":"https://github.com/litesql/pocketbase-ha","last_synced_at":"2026-04-18T19:04:16.608Z","repository":{"id":318878240,"uuid":"1073946266","full_name":"litesql/pocketbase-ha","owner":"litesql","description":"Highly available leader/leaderless PocketBase cluster powered by go-ha database/sql driver","archived":false,"fork":false,"pushed_at":"2026-01-16T18:15:11.000Z","size":1259,"stargazers_count":62,"open_issues_count":2,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-01-18T00:20:37.810Z","etag":null,"topics":["go","high-availability","pocketbase","sqlite"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/litesql.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-10T21:53:07.000Z","updated_at":"2026-01-16T18:33:17.000Z","dependencies_parsed_at":"2025-11-08T00:08:38.054Z","dependency_job_id":null,"html_url":"https://github.com/litesql/pocketbase-ha","commit_stats":null,"previous_names":["litesql/pocketbase-ha"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/litesql/pocketbase-ha","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litesql%2Fpocketbase-ha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litesql%2Fpocketbase-ha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litesql%2Fpocketbase-ha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litesql%2Fpocketbase-ha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/litesql","download_url":"https://codeload.github.com/litesql/pocketbase-ha/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/litesql%2Fpocketbase-ha/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28948358,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T14:26:55.697Z","status":"ssl_error","status_checked_at":"2026-01-31T14:26:52.545Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","high-availability","pocketbase","sqlite"],"created_at":"2026-01-17T00:47:51.439Z","updated_at":"2026-04-18T19:04:16.600Z","avatar_url":"https://github.com/litesql.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PocketBase HA\nHighly Available Leader/Leaderless [PocketBase](https://pocketbase.io/) Cluster powered by `go-ha` [database/sql driver](https://github.com/litesql/go-ha).\n\n## Features\n\n- **High Availability**: Run multiple PocketBase instances in a leader or leaderless cluster.\n- **Replication**: Synchronize data across nodes using NATS.\n- **Embedded or External NATS**: Choose between an embedded NATS server or an external one for replication.\n- **Remote direct access to Database**: via a secured gRPC endpoint for direct database access from remote clients. Use [terminal](#remote-database-access-from-terminal) or [DBeaver](https://github.com/litesql/jdbc-ha#dbeaver-integration).\n- **Undo transactions**: Use `pocketbase-ha cli` (or any gRPC client) to execute [UNDO](#undo-transactions) commands on already commited transactions. \n\n## Prerequisites\n\n- **Go**: Version `1.25` or later is required.\n\n## Installation\n\nDownload from [releases page](https://github.com/litesql/pocketbase-ha/releases/latest/).\n\n### Install from source\n\nInstall the latest version of `pocketbase-ha` using:\n\n```sh\ngo install github.com/litesql/pocketbase-ha@latest\n```\n\n### Docker image\n\n```sh\ndocker pull ghcr.io/litesql/pocketbase-ha:latest\n```\n\n### Install from helm\n\n- Add [litesql helm charts repository](https://litesql.github.io/helm-charts) to Helm:\n\n```sh\nhelm repo add litesql https://litesql.github.io/helm-charts\n```\n\n- Update the chart repository:\n\n```sh\nhelm repo update\n```\n\n- Deploy ha to kubernetes:\n\n```sh\nhelm install pb litesql/pocketbase-ha\n```\n\n- Visit [litesql helm charts repository](https://litesql.github.io/helm-charts) to customize the installation;\n\n\n## Configuration\n\nSet up your environment variables to configure the cluster:\n\n| Environment Variable | Description                                                                 | Default |\n|----------------------|-----------------------------------------------------------------------------|---------|\n| `PB_ASYNC_PUBLISHER` | Enables asynchronous replication message publishing. Recommended only when using an external NATS server. | false |\n| `PB_ASYNC_PUBLISHER_DIR` | Directory path for storing outbox messages used in asynchronous replication. |    |\n| `PB_GRPC_PORT` | TCP Port for the gRPC service to enable remote database access. | |\n| `PB_GRPC_TOKEN` | Authentication token for securing remote database access via gRPC. | |\n| `PB_LOCAL_HISTORY_MAX_AGE` | Local transactions history max age. Used in undo operations from CLI. Set to zero to disable _history.db | 24h |\n| `PB_LOCAL_TARGET`    | Specifies the service URL to redirect requests when this node is the leader. Useful for enabling leader election. | |\n| `PB_NAME`            | A unique name for the node. Defaults to the system's hostname if not provided. | $HOSTNAME |\n| `PB_NATS_PORT`       | Port for the embedded NATS server (use only if running an embedded NATS server). | |\n| `PB_NATS_STORE_DIR`  | Directory for storing data for the embedded NATS server.                   | /tmp/nats |\n| `PB_NATS_CONFIG`     | Path to a NATS configuration file (overrides other NATS settings).         | |\n| `PB_REPLICATION_URL` | NATS connection URL for replication (use if connecting to an external NATS server). Example: `nats://localhost:4222`. | |\n| `PB_REPLICATION_STREAM` | Stream name for data replication | pb |\n| `PB_ROW_IDENTIFY` | Strategy used to identify rows during replication. Options: `pk`, `rowid` or `full`. | pk |\n| `PB_STATIC_LEADER`| URL target to redirect all writer requests to the cluster leader | |\n| `PB_SUPERUSER_EMAIL` | Superuser email created at startup | |\n| `PB_SUPERUSER_PASS` | Superuser password created at startup | |\n\n## Usage\n\n### Starting a Cluster\n\n1. Start the first PocketBase HA instance:\n\n    ```sh\n    PB_NAME=node1 PB_NATS_PORT=4222 pocketbase-ha serve\n    ```\n\n2. Start a second instance in a different directory:\n\n    ```sh\n    PB_ASYNC_PUBLISHER=true PB_NAME=node2 PB_REPLICATION_URL=nats://localhost:4222 pocketbase-ha serve --http 127.0.0.1:8091\n    ```\n\n\u003e **Note**: You can skip setting the superuser password for the second instance.\n\n### Running a NATS Cluster with docker\n\nTo run a NATS cluster using Docker Compose, use the following command:\n\n```sh\ndocker compose up\n```\n\n- Superuser e-mail: test@example.com\n- Superuser pass: 1234567890\n\nYou can define the superuser password using this command:\n\n```sh\ndocker compose exec -e PB_NATS_CONFIG=\"\" -e PB_LOCAL_TARGET=\"\" node1 /app/pocketbase-ha superuser upsert EMAIL PASS\n```\n\nAccess the three nodes using the following address:\n\n- Node1: http://localhost:8090\n- Node2: http://localhost:8091\n- Node3: http://localhost:8092\n\n\u003e **Tip**: Ensure all nodes are synchronized by verifying the logs or using the PocketBase admin interface.\n\n### Event Hooks on replica nodes\n\nOn replica nodes (the nodes that users do not directly interact with), only the following events are triggered by the PocketBase event hooks system:\n\n- OnModelAfterCreateSuccess\n- OnModelAfterCreateError\n- OnModelAfterUpdateSuccess\n- OnModelAfterUpdateError\n- OnModelAfterDeleteSuccess\n- OnModelAfterDeleteError\n\n### Data Replication and Conflict Resolution\n\n**PocketBase HA** uses a last-writer-wins strategy for conflict resolution by default. To implement custom resolution strategies, modify the `ChangeSetInterceptor` in your code.\n\nFor applications that require strict consistency, configure a cluster leader to handle all write operations and prevent conflicts entirely.\n\n### Configuring a Cluster Leader\n\nSet `PB_LOCAL_TARGET` or `PB_STATIC_LEADER` environment variables to designate a leader node that processes all write requests:\n\n\n#### Static Leader\n\n```sh\nexport PB_STATIC_LEADER=http://leader-addr:8090\n```\n\n#### Dynamic Leader\n```sh\nexport PB_LOCAL_TARGET=http://local-advertise-addr:8090\n```\n\n\nThis ensures all mutations route through the leader while reads can be distributed across replica nodes.\n\n![write-path](./img/leader_write.png)\n\n![read-path](./img/leader_read.png)\n\n### Remote database access from terminal\n\nTo enable remote access, set `PB_GRPC_PORT` before starting the service:\n\n```sh\nexport PB_GRPC_PORT=9090\npocketbase-ha serve\n```\n\nThen, from another terminal, connect with:\n\n```sh\npocketbase-ha cli http://localhost:9090\n```\n\nThen execute any SQL command:\n\n```sh\ndata.db\u003e SELECT * FROM PRAGMA_table_list;\n```\n\n#### Protect the connection with a token\n\nSet `PB_GRPC_TOKEN` to require authentication for remote gRPC access.\n\n```sh\nexport PB_GRPC_PORT=9090\nexport PB_GRPC_TOKEN=secret\npocketbase-ha serve\n```\n\nThen, from another terminal, connect with:\n\n```sh\npocketbase-ha cli http://localhost:9090 --token secret\n```\n\n#### Undo transactions\n\nYou can undo transactions using `pocketbase-ha cli` UNDO command:\n\n```sh\n# connect\npocketbase-ha cli http://host:port\n\n# undo latest transaction\nundo;\n\n# undo last N transactions\nundo N;\n\n# undo transactions since time. Ex: undo 5m; (5 minutes ago)\nundo \u003ctime duration\u003e;\n\n# show the latest transaction\nhistory;\n\n# show the last N transactions\nhistory N;\n\n# show the transactions since time.\nhistory \u003ctime duration\u003e;\n```\n\n## Contributing\n\nContributions are welcome! Feel free to open issues or submit pull requests to improve this project.\n\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitesql%2Fpocketbase-ha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flitesql%2Fpocketbase-ha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flitesql%2Fpocketbase-ha/lists"}