added rust server
Build Unsigned iOS and macOS Apps / Build Unsigned iOS IPA (push) Canceled after 0s
Build Unsigned iOS and macOS Apps / Build macOS ZIP (push) Canceled after 0s

This commit is contained in:
wt committed 2026-10-29 18:05:24 +07:00
1 parent a2aa714a83
commit b32eabcd12
21 files changed
+5199 -143

No files matched your search

+47 -16
View File
@@ -1,6 +1,6 @@
# Balance Server
Self-hosted synchronization, account and web server for the Balance iOS, macOS, watchOS and Android applications. It is a single Go process with an embedded SQLite database and a complete browser client, and runs on Linux, Windows and macOS.
Self-hosted synchronization, account and web server for the Balance iOS, macOS, watchOS and Android applications. It is a single Rust process with a bundled SQLite engine and a complete browser client, and runs on Linux, Windows and macOS.
## Quick start with Docker
@@ -9,26 +9,28 @@ cp .env.example .env
openssl rand -base64 48
# Paste the generated value into BALANCE_JWT_SECRET in .env
docker compose up -d --build
curl http://localhost:8080/health
curl http://localhost:8123/health
```
Open `http://localhost:8080` to register or sign in to the web application. Data is kept in the `balance-data` Docker volume. Back it up while the container is stopped.
Open `http://localhost:8123` to register or sign in to the web application. Data is kept in the `balance-data` Docker volume. Back it up while the container is stopped.
## Run without Docker
Install Go 1.25 or newer, then run:
Install Rust 1.90 or newer, then build the locked dependencies:
```sh
go mod tidy
go build -o balance-server ./cmd/balance-server
cargo build --locked --release
```
The binary is `target/release/balance-server` (`balance-server.exe` on Windows).
SQLite is compiled into the binary; no separate SQLite service is needed.
On Linux or macOS:
```sh
export BALANCE_JWT_SECRET="replace-with-a-long-random-secret"
export BALANCE_DB_PATH="./data/balance.db"
./balance-server
./target/release/balance-server
```
On Windows PowerShell:
@@ -36,16 +38,13 @@ On Windows PowerShell:
```powershell
$env:BALANCE_JWT_SECRET = "replace-with-a-long-random-secret"
$env:BALANCE_DB_PATH = ".\data\balance.db"
.\balance-server.exe
.\target\release\balance-server.exe
```
Cross-compile release binaries from any Go installation:
```sh
GOOS=linux GOARCH=amd64 go build -o dist/balance-server-linux-amd64 ./cmd/balance-server
GOOS=darwin GOARCH=arm64 go build -o dist/balance-server-macos-arm64 ./cmd/balance-server
GOOS=windows GOARCH=amd64 go build -o dist/balance-server-windows-amd64.exe ./cmd/balance-server
```
For another platform, build on that platform or install its Rust target and C toolchain
for bundled SQLite. `cargo build --locked --release --target <target>` requires the
matching linker and C compiler. The retained Go implementation is a compatibility
reference and rollback option: `go build -o balance-server-go ./cmd/balance-server`.
After starting the binary, open `http://localhost:8080` in a browser. The web assets are embedded into the executable, so there is no separate frontend build, Node.js process or static directory to deploy.
@@ -83,7 +82,7 @@ Use HTTPS before exposing the server to a network. The Apple applications accept
```caddyfile
balance.example.com {
reverse_proxy 127.0.0.1:8080
reverse_proxy 127.0.0.1:8123
}
```
@@ -110,3 +109,35 @@ The sync endpoint accepts transactions, custom categories and monthly budgets. T
- Back up the SQLite database and its `-wal`/`-shm` files together, or stop the server before copying the database.
- Changing `BALANCE_JWT_SECRET` invalidates access tokens. Existing refresh sessions remain valid and will receive new access tokens after refresh.
- The in-process authentication limiter allows 30 authentication requests per IP per minute. Use a reverse proxy for stronger public rate limiting and request logging.
## Compatibility and migration
The Rust server retains the HTTP/JSON API, embedded web client, environment
variables, SQLite schema, Argon2id password hashes, JWT format, refresh sessions
and sync cursor semantics of the Go implementation. Docker Compose still maps
host port **8123** to container port **8080** and keeps `/data` in `balance-data`.
Direct binary execution defaults to port 8080.
Before replacing a running Go server, stop it, back up its database directory
(including any SQLite WAL/SHM files), and preserve `BALANCE_JWT_SECRET`. Start Rust
against the same `BALANCE_DB_PATH`; do not run both writers simultaneously.
Existing accounts, access/refresh tokens and saved device cursors remain usable.
See [deployment and rollback](docs/DEPLOYMENT.md) for the full procedure.
Verify the implementations locally with Go 1.25+, Rust and Python 3:
```sh
cargo test --locked
cargo fmt --check
cargo clippy --locked --all-targets -- -D warnings
cargo build --locked
python3 tools/compatibility.py
go test ./...
go vet ./...
go build ./...
```
The Python standard-library suite builds the Go reference, starts both binaries
on temporary loopback ports and databases, compares API responses and assets,
and tests SQLite takeover and rollback in both directions. To use release or
prebuilt executables, pass `--rust-binary PATH` and optionally `--go-binary PATH`.