diff --git a/POSTINSTALL.md b/POSTINSTALL.md index 97f2bd2..4d5d16b 100644 --- a/POSTINSTALL.md +++ b/POSTINSTALL.md @@ -46,14 +46,19 @@ Before using Ente, configure an S3-compatible object storage provider: ``` Verify with `curl -I -H 'Origin: https://ente.due.ren' `; you should see `Access-Control-Allow-Origin`. -Supported variables: +Supported variables (these map directly to the fields described in the upstream “Configuring Object Storage” documentation): - `S3_ENDPOINT` (e.g. `https://.r2.cloudflarestorage.com`) - `S3_REGION` - `S3_BUCKET` - `S3_ACCESS_KEY` - `S3_SECRET_KEY` - `S3_PREFIX` (optional path prefix) -- Optional replication: define `S3_SECONDARY_*` **and** `S3_COLD_*` (endpoints, keys, secrets, DC names) to mirror uploads to a second hot bucket and a third cold bucket. Replication is only enabled when all three buckets are configured; otherwise the app stays in single-bucket mode. See [Ente’s object storage guide](https://ente.io/help/self-hosting/administration/object-storage) for sample setups and discussion of reliability. +- `S3_ARE_LOCAL_BUCKETS` (set to `false` when your provider uses HTTPS “real” domains instead of MinIO-style LAN endpoints) +- `S3_FORCE_PATH_STYLE` (set to `true` for MinIO, Cloudflare R2, Backblaze, or any host that requires `https://host/bucket/object` URLs) +- `S3_PRIMARY_DC`, `S3_SECONDARY_DC`, `S3_COLD_DC`, `S3_DERIVED_DC` (advanced: override the canonical data-center identifiers if your Museum database already uses different keys; defaults follow the upstream docs: `b2-eu-cen`, `wasabi-eu-central-2-v3`, `scw-eu-fr-v3`) +- Optional replication: define **both** `S3_SECONDARY_*` and `S3_COLD_*` (endpoints, keys, secrets, optional prefixes, DC names) to mirror uploads to a second hot bucket and a third cold bucket. Replication is only enabled when all three buckets are configured; otherwise the app stays in single-bucket mode. See [Ente’s object storage guide](https://ente.io/help/self-hosting/administration/object-storage) for sample layouts and discussion of reliability. + +You should never edit the generated `/app/data/museum/configurations/local.yaml` directly. If you need to append extra settings (for example, defining `internal.super-admins`), create `/app/data/config/museum.override.yaml` and add only the keys you want to override. Copying the entire sample `s3:` block from the docs into that file will erase the credentials that the package renders from `s3.env` and break replication. ## Required: Secondary Hostnames diff --git a/README.md b/README.md index 0d5efcc..28ca3ab 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,12 @@ The app is configured automatically using Cloudron's environment variables for: After installing on Cloudron remember to: -1. Open the File Manager for the app, edit `/app/data/config/s3.env` with your object storage endpoint/keys, and restart the app. If you are using Cloudflare R2 or another S3-compatible service, configure the bucket’s CORS policy to allow the Ente frontends (e.g. `https://ente.due.ren`, `https://accounts.due.ren`, `https://cast.due.ren`, etc.) so that cast/slideshow playback can fetch signed URLs directly from storage. Replication requires **three** buckets: the primary (`S3_*`), a secondary hot bucket (`S3_SECONDARY_*`) and a cold bucket (`S3_COLD_*`). Once all three are configured the package will automatically enable replication on startup (watch `/app/data/logs/startup.log` for the “replication enabled” log line). See the [object storage guide](https://ente.io/help/self-hosting/administration/object-storage) for sample layouts and reliability notes. +1. Open the File Manager for the app, edit `/app/data/config/s3.env`, and set the S3-compatible credentials that belong in `museum.yaml`. The upstream documentation expects the canonical keys `b2-eu-cen` (primary), `wasabi-eu-central-2-v3` (secondary) and `scw-eu-fr-v3` (cold); this package renders those blocks automatically from the environment variables below so you don’t have to touch the generated config. At minimum set `S3_ENDPOINT`, `S3_REGION`, `S3_BUCKET`, `S3_ACCESS_KEY`, `S3_SECRET_KEY`, plus the optional `S3_PREFIX`. To enable replication you must also define **both** `S3_SECONDARY_*` and `S3_COLD_*` (endpoint, region, bucket, key, secret, optional prefix/DC overrides); after a restart the package will flip `replication.enabled` on your behalf when all three buckets are present. Advanced knobs from the documentation map to the following variables: + - `S3_ARE_LOCAL_BUCKETS=false` toggles SSL/subdomain-style URLs (`are_local_buckets` in `museum.yaml`); leave it at `true` for MinIO-style setups. + - `S3_FORCE_PATH_STYLE=true` translates to `use_path_style_urls=true` (required for R2/MinIO and most LAN storage). + - `S3_PRIMARY_DC`, `S3_SECONDARY_DC`, `S3_COLD_DC`, and `S3_DERIVED_DC` let you override the default data-center identifiers if your Museum database already uses different keys. + - Leave the generated `museum/configurations/local.yaml` alone—if you need to append extra settings, do so via `/app/data/config/museum.override.yaml` and only add the keys you actually want to change. Copy‑pasting the full sample `s3:` block from the docs will overwrite the generated credentials with blanks. + - If you are using Cloudflare R2 or another hosted S3 provider, configure your bucket’s CORS policy to allow the Ente frontends (e.g. `https://ente.due.ren`, `https://accounts.due.ren`, `https://cast.due.ren`, etc.) so that cast/slideshow playback can fetch signed URLs directly from storage. Backblaze B2 also requires clearing its “native” CORS rules; see the script in `POSTINSTALL.md`. 2. When prompted during installation, pick hostnames for the Accounts/Auth/Cast/Albums/Family web apps (they are exposed via Cloudron `httpPorts`). Ensure matching DNS records exist; Cloudron-managed DNS creates them automatically, otherwise point CNAME/A records such as `accounts.` at the primary hostname. 3. To persist tweaks to Museum (for example, seeding super-admin or whitelist entries), create `/app/data/config/museum.override.yaml`. Its contents are appended to the generated `museum/configurations/local.yaml` on every start, so you only need to declare the keys you want to override. ```yaml @@ -95,6 +100,16 @@ chown cloudron:cloudron /app/data/config/museum.override.yaml' The main photos UI continues to live on the hostname you selected during installation. +### Object storage quick reference + +The upstream documentation at [ente.io/help/self-hosting/administration/object-storage](https://ente.io/help/self-hosting/administration/object-storage) is written for bare-metal installs where you edit `museum.yaml` by hand. The Cloudron package wraps those steps so you only maintain `/app/data/config/s3.env`, but the same concepts apply: + +- **Canonical bucket names.** Museum’s schema ships with `b2-eu-cen`, `wasabi-eu-central-2-v3`, and `scw-eu-fr-v3`. You can point those names at any S3-compatible provider—the labels are just keys. If you do override them, update `S3_PRIMARY_DC`, `S3_SECONDARY_DC`, `S3_COLD_DC`, and restart so the package renders matching blocks. +- **Three buckets for replication.** Replication only works when two “hot” buckets and one “cold” bucket are configured. Populate `S3_*`, `S3_SECONDARY_*`, and `S3_COLD_*`; once all three have endpoints/keys/secrets the package automatically writes the `replication.enabled: true` stanza. +- **Transport settings.** Set `S3_ARE_LOCAL_BUCKETS=true`/`false` and `S3_FORCE_PATH_STYLE=true` to mirror the documentation’s `are_local_buckets`/`use_path_style_urls` toggles when talking to MinIO, Cloudflare R2, or other providers that require path-style URLs over HTTPS. +- **CORS.** If browsers cannot upload/download because of CORS, apply the recommended JSON from the docs (or the Backblaze helper script in `POSTINSTALL.md`). Ensure `Content-MD5` is listed in `AllowedHeaders` for providers with allow-lists. +- **Do not overwrite the generated config.** Keep `/app/data/config/museum.override.yaml` minimal (only the keys you need). Dropping the example `s3:` block from the docs into that file will clear the generated credentials and replication will fail with “PutObjectInput.Bucket” errors. + ## Usage ### Web Client diff --git a/start.sh b/start.sh index 2b37588..d6d7725 100755 --- a/start.sh +++ b/start.sh @@ -282,7 +282,6 @@ S3_COLD_BUCKET="${S3_COLD_BUCKET:-${ENTE_S3_COLD_BUCKET:-}}" S3_COLD_ACCESS_KEY="${S3_COLD_ACCESS_KEY:-${ENTE_S3_COLD_ACCESS_KEY:-}}" S3_COLD_SECRET_KEY="${S3_COLD_SECRET_KEY:-${ENTE_S3_COLD_SECRET_KEY:-}}" S3_COLD_PREFIX="${S3_COLD_PREFIX:-${ENTE_S3_COLD_PREFIX:-}}" -S3_COLD_DC_DEFAULT="${S3_COLD_DC:-${ENTE_S3_COLD_DC:-scw-eu-fr-v3}}" S3_COLD_DC_RAW="${S3_COLD_DC:-${ENTE_S3_COLD_DC:-}}" S3_COLD_ENABLED=false S3_COLD_ENDPOINT_HOST="" @@ -338,8 +337,12 @@ S3_FORCE_PATH_STYLE_RAW="${S3_FORCE_PATH_STYLE:-${ENTE_S3_FORCE_PATH_STYLE:-$DEF S3_FORCE_PATH_STYLE="$(printf '%s' "$S3_FORCE_PATH_STYLE_RAW" | tr '[:upper:]' '[:lower:]')" S3_ARE_LOCAL_BUCKETS="$(printf '%s' "${S3_ARE_LOCAL_BUCKETS:-${ENTE_S3_ARE_LOCAL_BUCKETS:-false}}" | tr '[:upper:]' '[:lower:]')" +DEFAULT_SECONDARY_DC="wasabi-eu-central-2-v3" +DEFAULT_COLD_DC="scw-eu-fr-v3" + S3_PRIMARY_DC="${S3_PRIMARY_DC:-${ENTE_S3_PRIMARY_DC:-b2-eu-cen}}" -S3_COLD_DC="${S3_COLD_DC_DEFAULT}" +S3_SECONDARY_DC="$DEFAULT_SECONDARY_DC" +S3_COLD_DC="$DEFAULT_COLD_DC" S3_DERIVED_DC="${S3_DERIVED_DC:-${ENTE_S3_DERIVED_DC:-$S3_PRIMARY_DC}}" S3_SECONDARY_ENV_PRESENT=false @@ -366,8 +369,6 @@ if [ "$S3_NOT_CONFIGURED" = "false" ] && [ "$S3_SECONDARY_ENV_PRESENT" = true ]; S3_SECONDARY_ENABLED=true if [ -n "$S3_SECONDARY_DC_RAW" ]; then S3_SECONDARY_DC="$S3_SECONDARY_DC_RAW" - else - S3_SECONDARY_DC="${S3_PRIMARY_DC}-secondary" fi fi else @@ -399,8 +400,6 @@ if [ "$S3_NOT_CONFIGURED" = "false" ] && [ "$S3_COLD_ENV_PRESENT" = true ]; then S3_COLD_ENABLED=true if [ -n "$S3_COLD_DC_RAW" ]; then S3_COLD_DC="$S3_COLD_DC_RAW" - else - S3_COLD_DC="$S3_COLD_DC_DEFAULT" fi fi else