Skip to content

Lite version for self-hosting - tested and working! #393

@luxzg

Description

@luxzg

Hey all!

I'll list a few things bellow, if this gets traction I'll be happy I helped, if not... so be it.

I've been waiting years for self-hosted Brave sync, and now that brave://flags finally has the experimental flag, and Android and desktop both work without issues, I went on with it.

But official go-sync server is complicated and heavy for self hosting:

  • reliance on Amazon / AWS DynamoDB
  • reliance on Redis
  • Docker as a recommended approach

Looking for an easier solution I've found a few blogs and posts describing how to make AWS database local, and some of those ended with 3 Docker containers, it was just too much for syncing 2 PCs and a phone.

So I've stumbled upon this project:
https://github.com/mikaelhg/litesync

It is sort of dormant, as the author was also waiting for the Android flag, but couple months passed since and no update.

I've jumped into discussion in their only issue:
mikaelhg/litesync#1

And ended up downloading the go-sync and pointing AI at it. Yup, I admit, I have zero knowledge about Go-lang programming, and don't have time reading all the docs. Sorry!

I had clear set of instructions:

  • I want a simplified service running on Linux (Debian/Ubuntu)
  • I wanted to keep as much of the original functionality completely unchanged
  • I wanted to remove reliance on AWS services or complicated databases, and instead use SQLite (it is for self-hosting, couple devices should have no issues with SQLite)
  • I wanted to remove reliance on Redis (again, self-hosting, less load, no need for overkills)

After initial review, I've decided to stay with Go, as I could keep most functionality unchanged, simply loading them as modules. That included parts or whole of:

github.com/brave/go-sync/auth
github.com/brave/go-sync/command
github.com/brave/go-sync/cache
github.com/brave/go-sync/schema/protobuf/sync_pb
github.com/brave/go-sync/datastore

Second decision was to also remove Prometheus and health checks, I didn't want any complications, so yeah, sorry. These can be added back in maybe as optional for folks that would like to monitor their sync server.

And finally I went with containing all changes inside sync-lite/ subfolder, including README; changelog, and other instructions.

I've also used the opportunity to give it a fix regarding the open issue :
brave/brave-browser#48909

So that's why it will work with both https://yourserver.com/v2/command and with https://yourserver.com/command
Other self-hosters currently work around the issue with additional reverse proxies and URL rewrites.

And last but not least is that it will support TLS certs directly, so again no need for additional proxies.
You can test it with http://localhost or use https://yourserver.com if you have domain and valid cert.
This was added due to warning on experimental flag where it clearly says only HTTP usage allowed is with localhost.

Some 7 hours later I had my very OK version 0.2 with confirmed and tested sync of bookmarks and tab groups between Android (Brave Nightly) and Debian desktop (Brave flatpack).

And thus my fork was born:
https://github.com/luxzg/go-sync/tree/master/sync-lite

It would be nice if someone could have a look, I am neither Go programmer nor do I know much about inner workings of the original go-sync. But I didn't want to wait forever for the next move and since I used ChatGPT (5.3, via Codex) for some other projects I gave it a go, and it works. And I want to share the code, and the idea, with everyone in Brave community, as I know there are people just waiting for easy way to self host.

My project includes the following (/sync-lite/ only):

  1. sync-lite/main.go
    Standalone sync-lite server entrypoint (HTTP/HTTPS, /command/ + /v2/command/, auth + protobuf request handling, graceful shutdown).

  2. sync-lite/sqlite_store.go
    SQLite datastore implementation replacing DynamoDB; schema creation, sync entity CRUD/query logic, disabled-chain handling, item counts, WAL checkpoint support.

  3. sync-lite/memory_cache.go
    In-memory cache adapter replacing Redis (implements expected cache interface methods).

  4. sync-lite/sync_lite_integration_test.go
    Integration tests for unauthorized access, commit/get-updates flow, disabled-chain behavior, gzip payloads, and multi-client isolation/conflict scenarios.

  5. sync-lite/go.mod
    Independent module definition for sync-lite with local replace to parent repo.

  6. sync-lite/go.sum
    Dependency checksums for the sync-lite module.

  7. sync-lite/README.md
    Project docs: scope, Brave URL behavior notes, config, Debian/Ubuntu deployment guide, service setup, testing instructions.

  8. sync-lite/CHANGELOG.md
    Versioned changelog (including tested 0.2 state and subsequent doc/template updates).

  9. sync-lite/deploy/sync-lite.env.example
    Sample environment configuration (listen address, SQLite path, TLS cert/key, optional client ID lists).

  10. sync-lite/deploy/sync-lite.service.example
    Sample systemd service unit for running sync-lite as a managed service.

  11. sync-lite/scripts/run-with-env.sh
    Helper script to load env file and run sync-lite without manual per-shell exports.

  12. sync-lite/DEVELOPMENT_SETUP.md
    Developer setup notes for VS Code/Codex workflow and local build steps.

  13. sync-lite/.gitignore
    Ignores local runtime/build artifacts (.env, binary, SQLite DB/WAL/SHM files).

(Heh, 13 files on Friday 13th, what could possibly go wrong :-) )

Please note that more about this idea, and the execution of the idea, is contained in the .md files, including README.md but also CHANGELOG.md and DEVELOPMENT_SETUP.md

For my background, while not a Go programmer, I'm a long time sysadmin, and have experience with PHP, Python, C++, and so on... but again, no Go, and I completely admit and even WARN that this was 99.9% made by AI (though under my supervision).

Even if code as such is rejected, it would be very nice if the idea persisted and was implemented, so that people can actually self host their sync servers - in an easy and lightweight way.

Thanks!

EDIT:
Code was made and built/compiled on Debian Trixie, uploaded binary to Ubuntu 24.04 server, runs as systemd service, and I have confirmed it syncs bookmarks and grouped tabs correctly using brave://flags/#brave-override-sync-server-url flag and usual brave://settings/braveSync/setup.
Except adding my own Let's Encrypt certificate to get HTTPS, nothing else was added, and everything is explained in readme (systemd service, env file, certs, etc).

EDIT:
I've now had more time and did more tests. I've tested 2-way sync from/to in all combinations I could think off between two Brave apps, one is Debian/flatpak other Android/APK (Nightly). Both setup with same sync server override URL, and everything turned on.

I can confirm syncs of:

  • passwords (1000+ imported, plus few manual inserts)
  • bookmarks, and bookmark folders
  • autofill data from address profiles
  • general autofill (form fields)
  • sessions
  • open tabs
  • tab groups
  • history
  • preferences (partial, probably need two desktops or two mobile to have better effect)

Also can confirm that data in SQLite is encrypted, and Sync Internals page brave://sync-internals/ shows Nigori keys.
Same Sync Internals page shows the data, and it's same data when opened on both devices.

Other than these tests and what I did earlier I don't know what else to do to confirm, in my opinion (based on the tests and general usage) it works, and it works well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions