Files
SyncGames/docs/nas-minio-cloudflare.md
T
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

82 lines
3.2 KiB
Markdown

# 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/](../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](../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`:
```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
```bash
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.