This document describes the process of migrating images from the Git repository to Supabase Storage to reduce repository size and improve performance.
Previous State:
/img directoryCurrent State:
/img directory excluded from Git (in .gitignore)To avoid re-downloading images on every Netlify build:
Netlify Cache Configuration (netlify.toml):
[[build.cache]]
paths = ["img/"]This caches the /img directory between builds.
Smart Download Script:
/img directory already has 200+ filesCache Invalidation:
netlify build --clear-cacheResult: Images are downloaded once, then reused from cache on subsequent builds.
New images are automatically uploaded to Supabase Storage via pre-push hook:
# 1. Add image to /img directory
cp new-image.jpg img/
# 2. Create content that references the image
echo '' >> content/posts/my-post.md
# 3. Commit and push (upload happens automatically)
git add .
git commit -m "Add new post with image"
git push # ← Image automatically uploaded to SupabaseHow it works:
scripts/pre-push-upload-images.js) runs before pushupsert: true to overwrite existing imagesBranch-aware behavior:
# On feature branch
git push # → Uploads to Preview Supabase
# On main branch
git push # → Syncs Preview to Production, then uploads local changesGitHub Actions Backup:
mainRequirements:
SUPABASE_SERVICE_ROLE_KEY and SUPABASE_SERVICE_ROLE_KEY_PREVIEW in .env and .env.previewIf you prefer manual control or the automatic upload fails:
# Upload to production
npm run migrate:images
# Upload to preview environment
npm run migrate:images:preview
# Dry-run to see what would be uploaded
npm run migrate:images:dry-runSupabase Service Role Key
.env or .env.preview:SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
SUPABASE_SERVICE_ROLE_KEY_PREVIEW=your_preview_service_role_keyDependencies
npm install glob mime-typesFirst, test the migration without actually uploading files:
# Test with preview branch
npm run migrate:images:dry-run -- --preview
# Or test with production
npm run migrate:images:dry-runThis will show:
Once you've verified the dry run, perform the actual upload:
# Upload to preview branch for testing
npm run migrate:images:preview
# Or upload to production
npm run migrate:imagesThe script will:
/img to Supabase Storage bucket imagesTest URL replacement without modifying files:
# Test with preview branch
npm run migrate:update-urls:dry-run -- --preview
# Or test with production
npm run migrate:update-urls:dry-runThis will show:
Perform the actual URL replacement:
# Update URLs for preview branch
npm run migrate:update-urls:preview
# Or update URLs for production
npm run migrate:update-urlsThe script will:
.md, .njk, and .html files/img/ paths with Supabase Storage URLsBuild and test the site with new image URLs:
npm run build
npm run serveVerify:
Push changes to staging branch for verification:
git add .
git commit -m "Migrate images to Supabase Storage"
git push origin feature/migrate-images-to-supabaseCreate a pull request and deploy to staging environment to verify in production-like conditions.
Once verified on staging:
# Remove /img directory
git rm -r img/
# Commit removal
git commit -m "Remove images from repository (now in Supabase Storage)"
# Add to .gitignore to prevent re-adding
echo "img/" >> .gitignore
git add .gitignore
git commit -m "Add img/ to gitignore"To reduce repository size by removing images from Git history:
# Install BFG Repo-Cleaner
brew install bfg
# Create backup
git clone --mirror https://github.com/cadextcp/RetroComputerDD.git
# Remove /img folder from history
bfg --delete-folders img --no-blob-protection RetroComputerDD.git
# Clean up
cd RetroComputerDD.git
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# Force push (coordinate with team!)
git push --force⚠️ Warning: Force pushing rewrites history. Coordinate with all team members before doing this.
Bucket Configuration:
imagesimage/jpeg, image/jpg, image/png, image/webp, image/svg+xml, image/gifFolder Structure:
The migration preserves the original folder structure:
images/
├── favicon/
│ ├── favicon.ico
│ └── ...
├── arcadeBuild/
│ ├── IMG_0130.JPG
│ └── ...
├── retroparty2024/
├── petRepair/
└── ...
Before:
After:
If issues occur after migration:
Revert URL changes:
git revert <commit-hash>Images are still in Git history (until Step 8), so they can be restored:
git checkout <previous-commit> -- img/Supabase Storage files remain and can be deleted if needed via Supabase Dashboard
Ensure the images bucket exists in Supabase Storage. Create it via:
scripts/migrate-images-to-supabase.js commentsSet the service role key in your environment:
# For preview
echo "SUPABASE_SERVICE_ROLE_KEY_PREVIEW=your_key" >> .env.preview
# For production
echo "SUPABASE_SERVICE_ROLE_KEY=your_key" >> .envCheck:
Run the update script again:
npm run migrate:update-urls:dry-runCheck which files weren't updated and why.
--preview flag first--dry-run flags to preview changes before applying