Files
SyncGames/docs/nas-minio-cloudflare.md
DawnsorrowandCursor 0d6b0b2f80 Initial SyncGames tree: agent, Android, deploy, docs.
Session-gated MinIO save sync with AppImage GUI, CLI edit/session flow, and Gitea release helper.

Co-authored-by: Cursor <[email protected]>
2026-07-14 22:06:36 -05:00

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:

  1. Bind API to 127.0.0.1:9000 (Compose does this).
  2. Create bucket syncgames (private) — docker compose --profile init run --rm createbuckets.
  3. Create an access key / secret for SyncGames devices (rotate periodically).
  4. 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

  1. Create Tunnel hostname syncgames-s3.<domain>http://127.0.0.1:80 (or whatever port NGINX listens on for that vhost).
  2. Prefer Cloudflare Access (email OTP / your IdP) for defense-in-depth.
  3. 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:

  1. Access Service Auth (service token headers) injected by agents — advanced, document if you enable it; or
  2. No Access on the S3 API hostname, protect with strong MinIO keys + tunnel (not publicly documented); or
  3. 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.