Skip to content

ManuJB023/manuel-serverless-image-uploader

Repository files navigation

Serverless Image Upload System

A full-stack serverless application for secure image uploads using AWS Lambda, S3, and DynamoDB with a React frontend.

πŸš€ Features

  • Serverless Architecture: Built with AWS Lambda for automatic scaling and cost efficiency
  • Secure Uploads: Pre-signed URLs for direct S3 uploads without exposing AWS credentials
  • Image Management: Store and retrieve image metadata using DynamoDB
  • CORS Enabled: Properly configured for cross-origin requests
  • Real-time Preview: Image preview before upload
  • Responsive UI: Clean React frontend with image gallery

πŸ—οΈ Architecture

Frontend (React) β†’ Lambda Function URL β†’ AWS Lambda β†’ S3 + DynamoDB

Components:

  • Frontend: React application for file selection and upload
  • AWS Lambda: Handles API requests and generates pre-signed URLs
  • Amazon S3: Stores uploaded images
  • DynamoDB: Stores image metadata (filename, upload time, S3 key)
  • Lambda Function URL: Direct HTTPS endpoint (no API Gateway needed)

🎯 Use Cases

1. Content Management Systems

Perfect for blogs, news sites, or documentation platforms where users need to upload images:

Blog Editor β†’ Upload Image β†’ Auto-resize/optimize β†’ Display in article

2. E-commerce Product Catalogs

Enable merchants to upload product images:

Merchant Portal β†’ Product Images β†’ S3 Storage β†’ CDN Distribution

3. Social Media Platforms

Handle user-generated content uploads:

User Profile β†’ Avatar Upload β†’ Secure Storage β†’ Display across platform

4. Real Estate Listings

Property managers uploading listing photos:

Property Form β†’ Multiple Images β†’ Organized Storage β†’ Gallery View

5. Educational Platforms

Students/teachers uploading assignments or course materials:

Course Materials β†’ Document/Image Upload β†’ Secure Access β†’ Download Links

πŸ› οΈ Technology Stack

Frontend

  • React 18 - Modern UI library
  • Axios - HTTP client for API calls
  • CSS3 - Styling and responsive design

Backend/Infrastructure

  • AWS Lambda - Serverless compute
  • Amazon S3 - Object storage
  • DynamoDB - NoSQL database
  • Lambda Function URLs - Direct HTTPS endpoints
  • AWS SDK v3 - Latest AWS JavaScript SDK

πŸ“‹ Prerequisites

  • Node.js 18+ and npm
  • AWS Account with appropriate permissions
  • AWS CLI configured locally

πŸš€ Installation & Setup

1. Clone the Repository

git clone https://github.com/yourusername/serverless-image-uploads.git
cd serverless-image-uploads

2. Install Frontend Dependencies

npm install

3. AWS Infrastructure Setup

Create S3 Bucket

aws s3 mb s3://my-serverless-image-uploads --region us-east-1

Create DynamoDB Table

aws dynamodb create-table \
    --table-name ImageUploads \
    --attribute-definitions AttributeName=id,AttributeType=S \
    --key-schema AttributeName=id,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST \
    --region us-east-1

Create Lambda Function

# Create deployment package
zip -r function.zip index.mjs

# Create Lambda function
aws lambda create-function \
    --function-name ImageUploadFunction \
    --runtime nodejs18.x \
    --role arn:aws:iam::YOUR_ACCOUNT:role/lambda-execution-role \
    --handler index.handler \
    --zip-file fileb://function.zip \
    --region us-east-1

Create Function URL

aws lambda create-function-url-config \
    --function-name ImageUploadFunction \
    --auth-type NONE \
    --cors '{
        "AllowCredentials": false,
        "AllowHeaders": ["content-type", "authorization"],
        "AllowMethods": ["*"],
        "AllowOrigins": ["*"],
        "MaxAge": 86400
    }' \
    --region us-east-1

4. Configure Environment

Update the LAMBDA_URL in src/App.js with your Function URL:

const LAMBDA_URL = 'https://your-function-url.lambda-url.us-east-1.on.aws/';

5. Run the Application

npm start

Visit http://localhost:3000 to use the application.

πŸ“ Project Structure

serverless-image-uploads/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ App.js              # Main React component
β”‚   β”œβ”€β”€ App.css             # Styling
β”‚   └── index.js            # React entry point
β”œβ”€β”€ public/
β”‚   └── index.html          # HTML template
β”œβ”€β”€ lambda/
β”‚   └── index.mjs           # Lambda function code
β”œβ”€β”€ README.md               # Project documentation
β”œβ”€β”€ package.json            # Dependencies
└── .gitignore             # Git ignore rules

πŸ” IAM Permissions

Your Lambda execution role needs these permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::my-serverless-image-uploads/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:PutItem",
                "dynamodb:GetItem",
                "dynamodb:Scan",
                "dynamodb:Query"
            ],
            "Resource": "arn:aws:dynamodb:us-east-1:*:table/ImageUploads"
        }
    ]
}

πŸ”„ API Endpoints

GET /

Retrieve all uploaded images

curl https://your-function-url.lambda-url.us-east-1.on.aws/

Response:

{
  "images": [
    {
      "id": "uuid",
      "filename": "image.jpg",
      "s3Key": "uploads/uuid-image.jpg",
      "contentType": "image/jpeg",
      "uploadedAt": "2025-06-18T00:21:17.000Z",
      "status": "pending"
    }
  ]
}

POST /

Generate pre-signed upload URL

curl -X POST https://your-function-url.lambda-url.us-east-1.on.aws/ \
  -H "Content-Type: application/json" \
  -d '{"filename":"test.jpg","contentType":"image/jpeg"}'

Response:

{
  "uploadUrl": "https://s3-presigned-url...",
  "imageId": "uuid",
  "s3Key": "uploads/uuid-test.jpg"
}

πŸ§ͺ Testing

Manual Testing

  1. Start the React app: npm start
  2. Open browser to http://localhost:3000
  3. Select an image file
  4. Click "Upload Image"
  5. Verify image appears in gallery

API Testing

# Test GET endpoint
curl https://your-function-url.lambda-url.us-east-1.on.aws/

# Test POST endpoint
curl -X POST https://your-function-url.lambda-url.us-east-1.on.aws/ \
  -H "Content-Type: application/json" \
  -d '{"filename":"test.jpg","contentType":"image/jpeg"}'

πŸ”§ Troubleshooting

Common Issues

  1. 403 CORS Error

    • Ensure Lambda Function URL has CORS configured
    • Check AllowOrigins includes your frontend URL
  2. DynamoDB Access Denied

    • Verify Lambda execution role has DynamoDB permissions
    • Check table name matches in code
  3. S3 Upload Failed

    • Confirm S3 bucket exists and is accessible
    • Verify pre-signed URL hasn't expired (5 minutes)
  4. Images Not Displaying

    • Check S3 bucket public access settings
    • Verify S3 key format in image URLs

πŸ’° Cost Considerations

This serverless architecture is cost-effective:

  • Lambda: Pay per request (first 1M requests/month free)
  • S3: Storage costs (~$0.023/GB/month)
  • DynamoDB: On-demand billing (first 25GB free)
  • Data Transfer: Minimal costs for typical usage

Estimated monthly cost for 1,000 image uploads: < $1

πŸš€ Deployment Options

Production Deployment

  1. Frontend: Deploy to S3 + CloudFront or Vercel/Netlify
  2. Lambda: Use AWS SAM or Serverless Framework
  3. Infrastructure: CloudFormation or Terraform

Environment Variables

For production, use environment variables:

const BUCKET_NAME = process.env.S3_BUCKET_NAME;
const TABLE_NAME = process.env.DYNAMODB_TABLE_NAME;

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • AWS SDK team for excellent documentation
  • React community for component patterns
  • Open source contributors

πŸ“ž Support

If you encounter any issues:

  1. Check the Troubleshooting section
  2. Review AWS CloudWatch logs for Lambda errors
  3. Open an issue on GitHub with error details

About

A full-stack serverless image uploader built with React, AWS Lambda, API Gateway, and S3 using pre-signed URLs.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages