-
Uses Sharp module to convert image to
progressive JPEGs(for now. May be to AVIF / JPEG XL in future considering wider browser compatibility) for multiple device types. -
Serves APIs(AWS Lambda) over api.momentcapturer.com(Set through API Gateway).
-
Stores processed images in AWS S3 bucket and cached for 1 year.
-
Records uploaded image metadata in AWS DynamoDB.
-
For serverless config, check out moment-capturer repo.
The sharp library uses native binaries that are platform-specific. When deploying from macOS to AWS Lambda (Linux ARM64), npm only installs macOS binaries by default.
Solution: Manually extract Linux ARM64 binaries before deployment:
# After npm install, manually add Linux binaries:
npm pack @img/sharp-linux-arm64@0.33.5
tar -xzf img-sharp-linux-arm64-0.33.5.tgz
mv package node_modules/@img/sharp-linux-arm64
rm img-sharp-linux-arm64-0.33.5.tgz
npm pack @img/sharp-libvips-linux-arm64@1.0.4
tar -xzf img-sharp-libvips-linux-arm64-1.0.4.tgz
mv package node_modules/@img/sharp-libvips-linux-arm64
rm img-sharp-libvips-linux-arm64-1.0.4.tgz
# Then deploy
serverless deployNote: Keep
sharpversion inpackage.jsonaligned with the binary versions above.
The getUploadUrl endpoint generates pre-signed URLs that allow browsers to upload directly to S3. For this to work, the S3 bucket must have CORS configured to allow PUT requests from the frontend origin.
Apply CORS configuration:
aws s3api put-bucket-cors --bucket moments-redefined --profile personal --cors-configuration file://cors-config.jsonVerify CORS:
aws s3api get-bucket-cors --bucket moments-redefined --profile personalRequired CORS rules (see cors-config.json):
AllowedMethods: Must includePUT(in addition toGET)AllowedOrigins: Must includehttps://momentcapturer.comAllowedHeaders:*(to allow Content-Type header)
Why is this needed? When browsers make cross-origin requests directly to S3 (e.g., uploading via pre-signed URL), S3 enforces CORS. Server-side uploads from Lambda don't require CORS since they're server-to-server.