3.2 KiB
3.2 KiB
Context
Phase 3 added local photo uploads to static/uploads/. Phase 6 moves them to MinIO (S3-compatible, self-hosted on .13) so they survive deploys and the admin can manage them. Both apps run on .13 alongside MinIO → no new firewall ports (the Go app serves photos through :3020, already open).
Goals / Non-Goals
Goals:
- Uploads go to MinIO; public page serves them via the Go app (
/photos/…). - Admin can upload photos to the same bucket (Filament S3 disk).
- Existing uploads migrated; external photo URLs keep working.
Non-Goals:
- Public bucket exposure (photos served through the app, not MinIO directly).
- Image resizing/optimisation (future).
- Cloud S3 (this is self-hosted; swapping to AWS S3 later = same S3 API).
Decisions
- MinIO on .13 at
/home/sam/Docker/Containers/wherewoof-minio/(compose: minio/minio server, API 9000, console 9001, volumewherewoof-minio-data; creds in a local.env, chmod 600). Create bucketwherewoofat startup (entrypointmcalias + mb, or a one-off). - Go storage via minio-go/v7:
UploadPhotoreads the multipart file →PutObjectto bucketwherewoof, keytags/{id}.{ext}→ setsphoto_url = /photos/tags/{id}.{ext}. Serve routeGET /photos/{key...}→GetObject→ stream withContent-Type+Cache-Control: public, max-age=86400. - Config:
MINIO_ENDPOINT(host:port),MINIO_ACCESS_KEY,MINIO_SECRET_KEY,MINIO_BUCKET(defaultwherewoof), env-driven; log-mode/no-op if unset (dev keeps working via the existing local fallback? — no: unset → upload returns a friendly error; local file upload is replaced). Decision: if MINIO_* unset, UploadPhoto responds "storage not configured" (dev DB tests unaffected — they don't upload). - Admin S3 disk:
composer require league/flysystem-aws-s3-v3;config/filesystems.phpaddsminiodisk (driver s3, endpoint http://minio:9000 from the admin container — via docker network or host IP 192.168.20.13:9000, use_ssl false); TagResource photo →FileUpload::make('photo_url')->disk('minio')storing totags/and setting the URL via the frontend domain (https://where-woof.com/photos/…). - Migration: one-off script copies
static/uploads/*objects into MinIO with matching keys (dev data; run once).
Risks / Trade-offs
- [MinIO creds in .env files] → chmod 600, gitignored, consistent with existing pattern.
- [Serving through the app adds a hop] → fine (same host, localhost); gives auth/cache control later.
- [Admin image preview needs the frontend URL] →
<img>cross-origin is fine; uses the public frontend domain. - [flysystem package version drift with Filament] → pin as Filament requires (uses its own storage config).
Migration Plan
- Provision MinIO on .13 (compose + env + bucket); verify with
mc/curl. - Go: add minio-go, UploadPhoto→S3, /photos/ route, config; build + verify suite (upload → served).
- Admin: s3 disk + Filament upload; verify via admin UI (browser).
- One-off migrate
static/uploads→ MinIO. - Deploy: frontend env + binary; admin .env + rebuild container. Verify live photo round-trip.
Open Questions
- Whether to keep the local
static/uploadsfallback for dev (decided: no — MinIO only; dev can point MINIO_ENDPOINT at the .13 instance).