Migrate all website images to permanent cloud storage
Update application to utilize Replit Object Storage for all uploaded member, competition, and sponsor images, ensuring permanent storage and updating database paths accordingly. Replit-Commit-Author: Agent Replit-Commit-Session-Id: cd9a7d26-a4e5-4215-975c-c59f4ed1f06d Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 74506617-f398-426d-a3f7-aa9d2fbde85b Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/d0a1d46d-d203-4308-bc6a-312ac7c0243b/cd9a7d26-a4e5-4215-975c-c59f4ed1f06d/62gjmyB
This commit is contained in:
@@ -1,118 +0,0 @@
|
||||
# 🗄️ Object Storage Setup Guide
|
||||
|
||||
## Problem: Images Disappearing After a Few Hours
|
||||
|
||||
Your website was saving uploaded images to the local filesystem (`static/images/`), which is **ephemeral storage** in Replit. This means files get automatically deleted after a few hours.
|
||||
|
||||
## Solution: Replit Object Storage (Persistent Storage)
|
||||
|
||||
I've updated your website to use **Replit Object Storage**, which is built on Google Cloud Storage and provides permanent file storage.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Setup Instructions (Required)
|
||||
|
||||
### Step 1: Create an Object Storage Bucket
|
||||
|
||||
1. Open the **Tools** panel in your Replit workspace (left sidebar)
|
||||
2. Click on **Object Storage**
|
||||
3. Click **"Create a Bucket"**
|
||||
4. Give it a name (e.g., `ftc-team-images`)
|
||||
5. Click **Create**
|
||||
|
||||
### Step 2: Set Environment Variable
|
||||
|
||||
1. Go to the **Secrets** tab in your Replit workspace (lock icon in left sidebar)
|
||||
2. Add a new secret:
|
||||
- **Key**: `OBJECT_STORAGE_BUCKET`
|
||||
- **Value**: Your bucket name (e.g., `ftc-team-images`)
|
||||
3. Click **Add Secret**
|
||||
|
||||
### Step 3: Restart the Server
|
||||
|
||||
1. Stop the Flask server if it's running
|
||||
2. Start it again (or let it auto-restart)
|
||||
|
||||
---
|
||||
|
||||
## ✅ How It Works Now
|
||||
|
||||
### Automatic Upload to Persistent Storage
|
||||
|
||||
All file uploads now go to Object Storage instead of local storage:
|
||||
|
||||
- **Member/Mentor Photos** → `members/` folder in your bucket
|
||||
- **Competition Images** → `competitions/` folder
|
||||
- **Sponsor Logos** → `sponsors/` folder
|
||||
|
||||
### Full Image URLs
|
||||
|
||||
Images are now stored as **full Google Cloud Storage URLs** like:
|
||||
```
|
||||
https://storage.googleapis.com/ftc-team-images/members/abc123.jpg
|
||||
```
|
||||
|
||||
These URLs are:
|
||||
- ✅ **Permanent** - Never get deleted
|
||||
- ✅ **Fast** - Served directly from Google's CDN
|
||||
- ✅ **Public** - Accessible from anywhere on the web
|
||||
- ✅ **Reliable** - Backed by Google Cloud infrastructure
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Code Changes Made
|
||||
|
||||
### New Files:
|
||||
- `object_storage.py` - Object storage service module
|
||||
- `OBJECT_STORAGE_SETUP.md` - This guide
|
||||
|
||||
### Updated Files:
|
||||
- `app.py` - All upload routes now use object storage
|
||||
- `add_member()` - Member/mentor images
|
||||
- `update_member()` - Member/mentor updates
|
||||
- `add_competition()` - Competition images
|
||||
- `edit_competition()` - Competition image updates
|
||||
- `add_sponsor()` - Sponsor logos
|
||||
|
||||
### Updated Dependencies:
|
||||
- Added `google-cloud-storage` package
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Testing
|
||||
|
||||
After setup, test by:
|
||||
|
||||
1. Go to `/admin/login` (password: `techturb123`)
|
||||
2. Upload a new member photo or competition image
|
||||
3. Check that the image displays correctly
|
||||
4. Wait a few hours - the image should still be there!
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Security Notes
|
||||
|
||||
- Object storage is authenticated automatically via Replit's infrastructure
|
||||
- All uploaded files are made publicly accessible (required for website images)
|
||||
- Files are organized into folders for easy management
|
||||
- Each file gets a unique UUID to prevent naming conflicts
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Important: Fallback Mode
|
||||
|
||||
If you haven't set up object storage yet, the website will still work using local storage (ephemeral):
|
||||
- You'll see a warning in the console: `"Warning: Object Storage not configured"`
|
||||
- Files will still be saved but **will disappear after a few hours**
|
||||
- Set up object storage ASAP to make uploads permanent!
|
||||
|
||||
---
|
||||
|
||||
## 📚 Additional Resources
|
||||
|
||||
- [Replit Object Storage Docs](https://docs.replit.com/hosting/deployments/object-storage)
|
||||
- [Google Cloud Storage](https://cloud.google.com/storage)
|
||||
|
||||
---
|
||||
|
||||
**Need Help?** If you have any issues with setup, check the console logs for error messages.
|
||||
47
replit.md
47
replit.md
@@ -3,39 +3,28 @@
|
||||
## Overview
|
||||
Flask-based website for FTC Team 23344 with a modern dark theme (#000000 pure black background), comprehensive content management system, PostgreSQL database integration, and premium smooth-scrolling animations.
|
||||
|
||||
## Recent Changes (November 13, 2025)
|
||||
## Recent Changes (December 13, 2025)
|
||||
|
||||
### Critical Fix: Persistent Object Storage for Uploaded Files
|
||||
Fixed the issue where uploaded images (members, mentors, competitions, sponsors) were disappearing after a few hours.
|
||||
### Complete Object Storage Migration
|
||||
All uploaded images are now stored permanently in Replit Object Storage, preventing the issue where files would disappear after a few hours.
|
||||
|
||||
**The Problem:**
|
||||
- Files were being saved to local filesystem (`static/images/`)
|
||||
- Local storage in Replit is **ephemeral** and gets cleared periodically
|
||||
- All uploaded images would vanish after a few hours
|
||||
**What Was Done:**
|
||||
1. Installed `replit-object-storage` official Python package
|
||||
2. Created `object_storage.py` using official Replit SDK
|
||||
3. Added `/storage/<path>` route to serve files from object storage
|
||||
4. Added `|image_url` Jinja template filter to handle both local and storage paths
|
||||
5. Migrated all existing member, mentor, competition, and sponsor images to object storage
|
||||
6. Updated database paths from `images/filename.jpg` to `/storage/folder/uuid.ext`
|
||||
|
||||
**The Solution:**
|
||||
- Migrated to **Replit Object Storage** (built on Google Cloud Storage)
|
||||
- All file uploads now go to **persistent, permanent storage**
|
||||
- Images are served directly from Google's CDN with full URLs
|
||||
**How It Works:**
|
||||
- New uploads go directly to object storage via `upload_file_to_storage()` helper
|
||||
- Database stores paths like `/storage/members/uuid.png`
|
||||
- Templates use `{{ image_path|image_url }}` filter which handles both formats
|
||||
- `/storage/` route serves files from object storage bucket
|
||||
- Background images (hero, team, etc.) remain local as they don't get erased
|
||||
|
||||
**Technical Implementation:**
|
||||
- Created `object_storage.py` module using Google Cloud Storage Python client
|
||||
- Updated all upload routes to use object storage:
|
||||
- `add_member()`, `update_member()` - Member/mentor photos
|
||||
- `add_competition()`, `edit_competition()` - Competition images
|
||||
- `add_sponsor()` - Sponsor logos
|
||||
- Intelligent fallback: uses local storage if object storage not configured
|
||||
- Files organized by type: `members/`, `competitions/`, `sponsors/` folders
|
||||
- Unique UUIDs prevent filename conflicts
|
||||
- Public URLs stored in database instead of local paths
|
||||
|
||||
**Setup Required (See OBJECT_STORAGE_SETUP.md):**
|
||||
1. Create bucket in Object Storage pane
|
||||
2. Set `OBJECT_STORAGE_BUCKET` environment variable
|
||||
3. Restart server
|
||||
|
||||
**Dependencies Added:**
|
||||
- `google-cloud-storage` (v3.5.0)
|
||||
**Bucket:** `ftc-team-images`
|
||||
**Package:** `replit-object-storage` (installed via pip)
|
||||
|
||||
## Recent Changes (November 12, 2025)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user