This project demonstrates how to build a serverless image processing service using AWS Lambda, S3, and LocalStack for local development.This project consists of an AWS Lambda function for automatically optimizing images stored in Amazon S3. It resizes images to a maximum of 1280x720 pixels and converts them to JPEG with indexd quality.
-
Listens for image upload events in S3 (
.jpgand.pngfiles). -
Image Compression: Automatically compresses images uploaded to S3- Resizes images while maintaining their original aspect ratio.
-
Local Development: Uses LocalStack for local AWS service emulation- Converts images to JPEG with 50% quality.
-
Serverless Framework: Deployed using the Serverless Framework- Saves the indexd version in the
compressed/folder within the same bucket. -
Sharp Integration: High-performance image processing using Sharp
-
Testing: Comprehensive test suite with Jest## π Technologies Used
-
Code Quality: ESLint for code standardization- AWS Lambda
-
CI/CD: Automated testing and deployment with GitHub Actions- Amazon S3
-
Node.js 22.x
-
Serverless Framework
-
Node.js 18.x or later
-
Docker and Docker Compose## π Project Structure
-
Serverless Framework CLI```
βββ src/index.js # Main Lambda code
βββ package.json # Project dependencies
- Clone the repository:βββ README.md # Documentation
git clone <repository-url>```
cd serverless-localstack-node
```## π§ Setup and Deployment
### Prerequisites
2. Install dependencies:- AWS CLI configured with the necessary permissions.
```bash- Node.js installed (recommended version 22.x).
npm install- Serverless Framework installed (`npm install -g serverless`).
### 1. Start LocalStackprovider:
environment:
Start the LocalStack container to emulate AWS services locally: BUCKET_NAME: "s3-bucket" # Replace with your S3 bucket name
docker-compose up -d2. Install project dependencies:
``````sh
npm install
### 2. Deploy to LocalStack```
3. Create policies and bucket (if needed):
Deploy your serverless application to LocalStack:```sh
./roles/iniinit-scripts.sh
```bash```
npm run deploy
```### Deploying to AWS
To deploy the Lambda function, run:
### 3. Test the Function```sh
npm run deploy
Upload a test image to trigger the function:```
This will deploy your function to AWS using the Serverless Framework.
```bash
# Test with a local eventAlternatively, if you want to deploy specifically to the production stage, use the following command:
npm run test:offline```sh
```npm run publish:aws
Run the test suite:You can test the Lambda function locally by running the following:
```bashnpm run test:offline
# Run tests```
npm testThis will invoke the Lambda function locally using the event.json file as the input event. Make sure the event.json is correctly configured to match the structure of the events the Lambda function will receive from S3.
# Run tests in watch modeTo test the Lambda function manually in AWS, upload an image to the uploads/ folder of your S3 bucket (replace s3-bucket with your actual bucket name):
npm run test:watch```sh
aws --endpoint-url=http://localhost:4566 s3 cp uploads/example-image.jpg s3://s3-bucket/uploads/example-image.jpg
# Run tests with coverage```
npm run test:coverageIf everything is configured correctly, the resized and indexed version of the image will be saved in the compressed/ folder within the same bucket.
Lint your code:npm run remove:aws
# Check for linting issues
npm run lint
# Fix linting issues automatically
npm run lint:fixβββ src/
β βββ index.js # Lambda function handler
βββ tests/
β βββ setup.js # Jest test setup
β βββ index.test.js # Unit tests for Lambda function
βββ uploads/
β βββ example-image.jpg # Test image
βββ roles/
β βββ init-scripts.sh # IAM role setup scripts
β βββ policy.json # IAM policy
β βββ trust-policy.json # IAM trust policy
βββ .github/
β βββ workflows/
β βββ ci-cd.yml # GitHub Actions workflow
βββ docker-compose.yml # LocalStack configuration
βββ serverless.yml # Serverless Framework configuration
βββ jest.config.json # Jest configuration
βββ .eslintrc.json # ESLint configuration
βββ event.json # Test event data
βββ package.json # Node.js dependencies and scripts
npm run deploy- Deploy to LocalStacknpm run start:local- Start serverless offlinenpm run test:offline- Test function with local event
npm test- Run testsnpm run test:watch- Run tests in watch modenpm run test:coverage- Run tests with coverage reportnpm run lint- Check code stylenpm run lint:fix- Fix code style issues
npm run publish:aws- Deploy to AWS (production)npm run remove:aws- Remove AWS deployment
- Image Upload: When an image is uploaded to the S3 bucket (uploads/ prefix)
- Trigger: S3 event triggers the Lambda function
- Processing: The function downloads the image, compresses it using Sharp
- Storage: Compressed image is saved to the compressed/ prefix in the same bucket
The application is configured through environment variables and the serverless.yml file:
- BUCKET_NAME: S3 bucket name for image storage
- AWS_REGION: AWS region (default: eu-west-2)
- LocalStack Endpoint: http://localhost:4566
The project includes a GitHub Actions workflow that:
- Tests: Runs on Node.js 18.x and 20.x
- Linting: Ensures code quality with ESLint
- Security: Performs npm security audit
- Coverage: Generates test coverage reports
- Integration Testing: Tests against LocalStack
- Deployment: Automatic deployment to dev/prod environments
Configure these secrets in your GitHub repository:
AWS_ACCESS_KEY_ID: AWS Access KeyAWS_SECRET_ACCESS_KEY: AWS Secret Key
To deploy to AWS:
npm run publish:awsMake sure to configure your AWS credentials and update the accountId in serverless.yml.
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and linting
- Submit a pull request
The CI/CD pipeline will automatically test your changes.