Session-gated MinIO save sync with AppImage GUI, CLI edit/session flow, and Gitea release helper. Co-authored-by: Cursor <[email protected]>
3.2 KiB
MinIO + NGINX + Cloudflare
WAN path for SyncGames SSOT. Laptop and phone use this HTTPS endpoint only (no LAN/VPN requirement).
Topology
Clients → https://syncgames-s3.<your-domain>
→ Cloudflare DNS (+ optional Access)
→ cloudflared Tunnel
→ NGINX on NAS
→ MinIO S3 API :9000
Keep MinIO Console (often :9001) on a separate vhost or LAN-only. SyncGames clients need the S3 API only.
MinIO
Prefer Docker on the NAS: deploy/docker/ (docker compose up -d).
Manual checklist:
- Bind API to
127.0.0.1:9000(Compose does this). - Create bucket
syncgames(private) —docker compose --profile init run --rm createbuckets. - Create an access key / secret for SyncGames devices (rotate periodically).
- Set
MINIO_SERVER_URL=https://syncgames-s3.<your-domain>so redirects/presigns use the public name if you use them (SyncGames prefers path-style without relying on redirects).
NGINX (anti-grief checklist)
Example vhost: deploy/nginx/syncgames-s3.conf
Required behaviors:
| Setting | Why |
|---|---|
Preserve Host as public hostname |
SigV4 signing |
proxy_request_buffering off |
Avoid truncated large PUTs |
client_max_body_size 512m; (or higher) |
Emulator dumps |
proxy_http_version 1.1 |
Keepalive / chunked |
ignore_invalid_headers off |
S3 headers with underscores |
Forward Authorization, X-Amz-*, Content-Length, X-Forwarded-Proto |
API correctness |
No auth_basic |
Breaks AWS SDKs — use Cloudflare Access instead |
Cloudflare
- Create Tunnel hostname
syncgames-s3.<domain>→http://127.0.0.1:80(or whatever port NGINX listens on for that vhost). - Prefer Cloudflare Access (email OTP / your IdP) for defense-in-depth.
- Orange-cloud proxy is fine for typical Souls/ER save sizes. If a huge upload fails (~100MB free-plan body limits can apply depending on product), check Cloudflare docs / plan or temporarily use a larger object split strategy.
Client configuration
In agent.toml:
endpoint_url = "https://syncgames-s3.example.com"
bucket = "syncgames"
region = "us-east-1"
path_style = true
access_key = "..."
secret_key = "..."
Android settings screen uses the same values.
Validation
syncgames doctor
Performs HEAD/list on the bucket and a tiny PUT/GET/DELETE probe object under games/_probe/. Failures usually mean Host/header/buffering misconfig on NGINX or Access blocking SDK traffic (use a Service Token or bypass path carefully for API clients if Access challenges browsers only — for programmatic S3, Access service tokens or skip Access on the API hostname and rely on MinIO keys + Cloudflare WAF IP restrictions).
Cloudflare Access vs S3 SDKs
Browser Access login does not work for boto3/Android AWS SDK. Pick one:
- Access Service Auth (service token headers) injected by agents — advanced, document if you enable it; or
- No Access on the S3 API hostname, protect with strong MinIO keys + tunnel (not publicly documented); or
- Separate hostname for human console only behind Access.
Recommended v1: tunnel + strong MinIO keys; optional IP allowlist / WAF; Access only on MinIO Console vhost if exposed.