Files
ubuntu-post-install/services
Claude d2848cecc3 immich: add native S3 storage engine support for thumbnails/uploads
Adds an opt-in prompt to store Immich-managed data (thumbnails, encoded
video, new uploads) in S3-compatible object storage instead of local
disk, using Immich's native IMMICH_STORAGE_ENGINE=s3 — deliberately NOT
a FUSE-mounted bucket. Checked this against real reported issues before
implementing: Immich uses symlinks internally that S3 doesn't support
under FUSE (ENOSYS errors), and its startup does thousands of stat()/
read() calls that FUSE-over-network handles badly enough to crash the
mount under latency spikes as small as 100ms. Native S3 mode talks to
the bucket over the S3 API directly, sidestepping both problems.

Independent of the existing external-library strategy — an external
library (existing photos indexed read-only, e.g. over a VPN mount) is
a separate mount either way and works the same regardless of where
Immich's own managed data lives, since S3 mode only replaces
UPLOAD_LOCATION.

- New prompts: bucket, region, endpoint (for non-AWS S3-compatible
  providers — auto-sets S3_FORCE_PATH_STYLE when given), prefix, access
  key ID, and secret key (read via `read -rs` so it doesn't echo; left
  blank with a warning under UNATTENDED, since there's no sane default).
- Refactored the docker-compose.yml generation from two near-duplicate
  heredocs (with/without external library) into one with composable
  volume-line variables, to avoid quadrupling the duplication once S3
  was added as a second axis.
- Skips creating local upload-location subdirectories entirely in S3
  mode (thumbs/upload/backups/library/profile/encoded-video) — Immich
  manages that structure inside the bucket itself.
- .env now gets chmod 600 (previously ungated) — more pointed now that
  it can hold an S3 secret key, not just the DB password.
- Generated README documents the S3 setup and carries the FUSE-mount
  warning forward so a future reader doesn't try that route instead.

Verified both the non-S3 baseline (unchanged output) and S3 mode
end-to-end via non-interactive dry runs — correct .env, correct
compose volumes, no local upload dirs created, 0600 permissions.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TBtExJcqxnokyZZKmphdug
2026-08-09 20:06:50 +00:00
..