Validate, publish, and deploy Brave Sync / validate (push) Successful in 14s
Validate, publish, and deploy Brave Sync / image (push) Failing after 25s
Validate, publish, and deploy Brave Sync / chart (push) Skipped
Validate, publish, and deploy Brave Sync / deploy (push) Skipped
33 lines
5.4 KiB
Markdown
33 lines
5.4 KiB
Markdown
# Brave Sync at sync.brunner.ninja
|
|
|
|
This chart runs the [official Brave Sync v2 server](https://github.com/brave/go-sync) from the commit in `upstream-commit.txt`. The app image is built by Gitea Actions because Brave does not publish an official container image. DynamoDB Local holds the encrypted sync entities on a `rook-ceph-block` PVC. Valkey provides the server cache. The Sync API is published through Traefik with a cert-manager certificate.
|
|
|
|
The service has no web UI or interactive login. `https://sync.brunner.ninja/` returns a simple HTTP heartbeat; browsers use the `/v2/command/` API. Brave authenticates with a Sync Chain code and encrypts sync data before upload. Keep that code private and back it up separately. The server still sees metadata such as device information and item IDs. Brave Sync supports passwords, bookmarks, history, and other enabled sync types, but it is not a complete browser profile backup; check the options on every device and keep independent backups of valuable data.
|
|
|
|
## Versioning
|
|
|
|
Edit only `chart-version.txt` for a new base chart version. CI packages a unique version `<base>-r<run number>` on each push to `main`, with `appVersion` set to the exact immutable `sha-<commit>` image tag from that run. `Chart.yaml` contains a fixed placeholder because Helm requires that field in source charts; `package.sh` replaces it when packaging. `values.yaml` contains only the HTTPS hostname; fixed image versions and homelab defaults live in the templates. To update Brave server source, set `upstream-commit.txt` to a reviewed full upstream commit and push the change.
|
|
|
|
## Initial setup
|
|
|
|
1. Create the Gitea repository yourself, push this local repository's `main` branch, and configure `QUAY_USERNAME`, `QUAY_TOKEN`, `PACKAGE_USERNAME`, `PACKAGE_TOKEN`, and later `KUBE_CONFIG_BASE64` as Gitea Actions repository secrets. The Quay repository path is `registry.brunner.ninja/feedc0de/brave-sync`.
|
|
2. The initial rollout created a Cloudflare CNAME from `sync.brunner.ninja` to `brunner.ninja` and cert-manager issued `brave-sync-tls`. For a fresh installation elsewhere, create equivalent DNS before connecting browsers.
|
|
3. Wait for the first `main` CI run to publish the image and chart. Its image tag is `sha-<first 12 characters of commit SHA>`.
|
|
4. Bootstrap the namespace and copy the existing homelab Quay pull credentials with `./bootstrap.sh`. This copy stays within the homelab cluster. The initial rollout has already completed this step.
|
|
5. Run `IMAGE_TAG=sha-<first 12 characters of commit SHA> ./install.sh`. The script checks the default context, lints/renders the chart, performs server dry-runs, then runs `helm upgrade --install --wait`. The initial rollout has already installed the chart.
|
|
6. The limited deployer ServiceAccount and Role already exist. Run `./create-ci-kubeconfig.sh` and store its single-line output only in the `KUBE_CONFIG_BASE64` Gitea secret. Do not commit it. Then rerun the workflow or push the next change. CI can update only the named workload objects; it cannot read Kubernetes Secrets or create/delete workloads.
|
|
|
|
The published chart is available via `helm repo add brunner https://brunner.ninja/charts && helm repo update brunner`. `install.sh` is kept for manual deployments. CI renders the same chart and patches the named existing resources, since Helm release storage would require CI to read Kubernetes Secrets. A later manual Helm upgrade reconciles Helm's stored release revision with the latest chart.
|
|
|
|
For other clusters, the chart also accepts optional `ingressClassName`, `clusterIssuer`, `storageClassName`, and `imagePullSecret` values. The committed `values.yaml` remains only the hostname. Set `imagePullSecret: ""` for anonymous pulls of the public Quay image. The Traefik compatibility route is installed only when `ingressClassName` is `traefik`; other ingress controllers need their own rewrite rule if a Brave client drops `/v2` from the custom URL. cert-manager and an ingress controller are prerequisites. Create DNS and a matching ClusterIssuer before expecting HTTPS to work.
|
|
|
|
## Connect a Brave browser
|
|
|
|
On each supported Brave device, set `brave://flags/#brave-override-sync-server-url` to `https://sync.brunner.ninja/v2`, relaunch, and confirm the endpoint in `brave://sync-internals/`. Then create or join the Sync Chain at `brave://settings/braveSync/setup`. Enable the data types you want on each device. A compatibility route handles Brave versions that strip `/v2` from the custom URL after relaunch. Do not put Authentik forward authentication on this API; browser sync requests cannot complete its interactive login. On platforms where the flag is unavailable, a client policy or `--sync-url=https://sync.brunner.ninja/v2` may be required.
|
|
|
|
Avoid moving an existing production Sync Chain blindly. Export passwords and bookmarks before switching its endpoint and confirm sync on a second test profile first. Each device in a chain must point to the same server.
|
|
|
|
## Check health and backups
|
|
|
|
`./test.sh` lints and renders the chart without duplicating deployment values. `./smoke-test.sh IMAGE` runs a real server with DynamoDB Local and Valkey in Podman and verifies its HTTP command path. After installation, check `kubectl -n brave-sync get pods,ingress,pvc,certificate`, `helm -n brave-sync status brave-sync`, and `brave://sync-internals/`. Back up the `data-brave-sync-dynamodb-0` PVC regularly; the server stores the encrypted Sync Chain data there. Test restoring it before relying on this instance as the only copy of credentials.
|