Migrate MinIO to SeaweedFS
New installs use SeaweedFS 4.47, pinned by image digest. Existing MinIO data
cannot be mounted into SeaweedFS: their disk formats are different. Keep the
old minio-data volume and its credentials until the migration is verified.
Upgrading the compose file alone creates an empty seaweedfs-data volume; it
does not copy your files.
Copy before switching
Section titled “Copy before switching”- Back up Postgres,
.envand the current compose file. Record your actual compose project name and bucket name. Use that same project name throughout. - Stop API and worker so uploads and background jobs cannot change files.
Leave the existing MinIO running. Do not run
down -vorSCANI_RESET=1. - Start only the SeaweedFS service from the new compose file, temporarily
with
SEAWEEDFS_S3_HOST_PORT=9002so it can coexist with MinIO on port 9000. SetS3_ACCESS_KEY_ID,S3_SECRET_ACCESS_KEYandS3_BUCKETto your chosen local storage credentials and existing bucket name. These are infrastructure secrets, not new cloud-provider API keys. - Configure two authenticated S3 remotes in
rclone:oldat your MinIO endpoint, andnewathttp://127.0.0.1:9002. Choose S3-compatible storage, explicit credentials, and path-style access. Keep the config protected and out of git. Do not put credentials directly on command lines. - Copy and verify all objects, replacing
job-uploadswith your bucket:
rclone copy old:job-uploads new:job-uploads --metadatarclone check old:job-uploads new:job-uploads --download--download verifies content even when multipart ETags differ between stores.
Do not rely only on object counts. These commands copy current objects; if you
use versioning, retention locks or custom bucket policies, export and restore
those separately before cutover. Scani’s bundled bucket does not enable them.
Cut over and verify
Section titled “Cut over and verify”- Stop the old MinIO service without deleting its volume. Set the SeaweedFS host port back to 9000 (or your chosen port), then recreate SeaweedFS.
- Set
S3_ENDPOINT=http://seaweedfs:8333on API and worker. SetS3_PUBLIC_ENDPOINTto the browser-reachable HTTPS S3 origin. Ensure the reverse proxy preserves the original Host header and path. Keep the same bucket and object keys, so existing database references remain valid. - Start API and worker. Open an existing document, download it, upload a new document and process an import. Verify signed uploads and downloads, and confirm an unsigned object read is denied.
- After verification, set
SCANI_STORAGE_MIGRATED=1in your protected.envso the installer can distinguish a completed migration from an empty new bucket while the old MinIO volume remains. - Take a SeaweedFS backup and test restoring it into an isolated instance. Retain the old MinIO volume and original compose file through your rollback window. Remove them only after you are satisfied with the migration.
For rollback, stop writers, copy and verify any new objects back to MinIO, restore the previous S3 endpoint/configuration, then restart the old service and writers. Pointing at the old bucket without copying post-cutover uploads back would leave those documents missing.
Tier 2 still uses customer-owned S3 after this change. Only processing inputs travel to Scani Cloud; neither this migration nor a tier change uploads your bucket to Scani. See Tier 2 wiring and backup and restore.