{"id":13680046,"url":"https://github.com/sagidM/s3-resizer","last_synced_at":"2025-04-29T19:32:36.609Z","repository":{"id":45781101,"uuid":"102974046","full_name":"sagidM/s3-resizer","owner":"sagidM","description":"AWS Lambda for resizing images in S3 on fly.","archived":false,"fork":false,"pushed_at":"2023-04-01T21:09:43.000Z","size":8687,"stargazers_count":224,"open_issues_count":3,"forks_count":78,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-11T22:35:57.269Z","etag":null,"topics":["amazon-s3","aws-lambda","microservice"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sagidM.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-09-09T17:49:34.000Z","updated_at":"2024-10-24T09:45:01.000Z","dependencies_parsed_at":"2024-01-14T14:55:54.317Z","dependency_job_id":"39ce6123-cd44-4cb0-a72d-fe605147e451","html_url":"https://github.com/sagidM/s3-resizer","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sagidM%2Fs3-resizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sagidM%2Fs3-resizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sagidM%2Fs3-resizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sagidM%2Fs3-resizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sagidM","download_url":"https://codeload.github.com/sagidM/s3-resizer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251569581,"owners_count":21610581,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amazon-s3","aws-lambda","microservice"],"created_at":"2024-08-02T13:01:12.510Z","updated_at":"2025-04-29T19:32:32.974Z","avatar_url":"https://github.com/sagidM.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"## What is it?\n\nIt's AWS Lambda, which is a compute service that lets you run code without provisioning or managing servers.  \n\u003e _[Read more about AWS Lambda.](http://docs.aws.amazon.com/lambda/latest/dg/welcome.html)_\n\n\n## Demo\nhttps://sagidm.github.io/smartuploader/examples/4.s3-resizer.html\n\n\n## What this lambda provides\nLet's say we have some _shared image_ in **S3**, for example:  \n`https://example.com/images/pretty_photo.jpg`  \n\nto resize on fly this image to, say, _150x150_, we can make a request like this:  \n`https://example.com/images/150x150/pretty_photo.jpg`  \n\nSo, if there's not image in this path, it's redirected to lambda and, after a moment, lambda creates the suitable image and then redirects back. We'll obviously have a new image next time.\n\n*** \nInstead of `WxH` there're some extra available _magic paths_:  \n`.../AUTOx150/...`  \n`.../150xAUTO/...`  \nor  \n`.../150x150_max/...`  \n`.../150x150_min/...`  \n\n\u003e Note that **s3-resizer** **does not enlarge an image** if the original image width or height are less than the requested dimensions. You can read about **[withoutEnlargement](https://sharp.pixelplumbing.com/en/stable/api-resize/#parameters)** method.\n\n\n## Setting up\n\n#### To resize images we need a storage, which is _S3_ (but could be CloudFront), and _Lambda_ function. Then we should set up all the permissions and redirection rules.\n\n* Create a **Bucket**  \n* * Go to [Services -\u003e Storage -\u003e S3](https://s3.console.aws.amazon.com/s3/home)\n* * Click on the blue button **Create bucket**\n* * Enter the name and click on **Create**\n\n* Create a **Lambda**\n* * Go to [Services -\u003e Compute -\u003e Lambda](https://console.aws.amazon.com/lambda/home)\n* * **Create a function -\u003e Author from scratch**\n* * Enter a name (e.g. s3-resizer)\n* * Select the latest version of Node.js according to [Releases](https://github.com/sagidM/s3-resizer/releases) (you can change it later)\n* * You need a role that has permission to **put** objects to your storage (aka policy). If you click on **Create function**, a default role will be created. You can edit it later or you can create and set up a role right now. To do that,\n* * There should be a link to [IAM console](https://console.aws.amazon.com/iam/home#/roles), go to there.\n* * * then **Create role -\u003e Lambda -\u003e Next: Permissions -\u003e Create policy**, a new tab should open\n* * * on that tab, you can use **Visual Editor** or add this JSON\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"logs:CreateLogGroup\",\n        \"logs:CreateLogStream\",\n        \"logs:PutLogEvents\"\n      ],\n      \"Resource\": \"arn:aws:logs:*:*:*\"\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": \"s3:PutObject\",\n      \"Resource\": \"arn:aws:s3:::__BUCKET_NAME__/*\"\n    }\n  ]\n}\n```\n\u003e Pay attention to `__BUCKET_NAME__`\n\n* * * Name your policy, for example: *\"access_to_putObject_policy\"* and click on **Create policy**; you can close the tab\n\n* * * On the previous tab, update the policy list clicking on the button with reload image or reloading the page.\n* * * Select your policy clicking on the checkbox\n* * * Click on **Next: tags -\u003e Next: Review**, name your role, for example, *\"access_to_putObject_role\"*\n* * * Click on **Create role**; you can close the tab.\n\n* * Now you are again on the lambda creating page.\n* * Select **Use an existing role** and choose your role in the list, update the list if necessary.\n* * After clicking on **Create function**, the lambda should be created.\n\n* Add a trigger, which will listen to http requests\n* * **YOUR_LAMBDA -\u003e Add trigger -\u003e API Gateway**\n* * You can select api that has prefix **-API** or **Create a new API**\n* * In **Security**, select **Open**, then click **Add**\n* * Now if you click on **API Gateway**, you should see **API endpoint**, something like  \n`https://some-id.execute-api.eu-central-1.amazonaws.com/your-stage/your-lambdas-name`\n\n* Set up Static website hosting\n* * Having an API endpoint, go to your bucket created at the beginning and add permissions\n* * * **YOUR_BUCKET -\u003e Permissions -\u003e Block public access -\u003e Edit**, uncheck **Block all public access**, **Save -\u003e Confirm**\n* * * **YOUR_BUCKET -\u003e Permissions -\u003e Bucket policy** and paste\n```json\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"AddPerm\",\n            \"Effect\": \"Allow\",\n            \"Principal\": \"*\",\n            \"Action\": \"s3:GetObject\",\n            \"Resource\": \"arn:aws:s3:::__BUCKET_NAME__/*\"\n        }\n    ]\n}\n```\n\u003e Pay attention to `__BUCKET_NAME__`. By the way, you are able to give an access not only to the whole bucket but also to a specific directory providing its path instead of __*__.\n* * Go to **Properties (next to Permissions) -\u003e Static website hosting -\u003e Select \"Use this bucket to host a website\"**\n* * In **Index document** paste any file, it'd be logical to name it _\"index.html\"_\n* * Paste this **Redirection rules**\n```json\n[\n  {\n    \"Condition\": {\n      \"HttpErrorCodeReturnedEquals\": \"404\"\n    },\n    \"Redirect\": {\n      \"Protocol\": \"https\",\n      \"HostName\": \"__DOMAIN__\",\n      \"ReplaceKeyPrefixWith\": \"__PATH_TO_LAMBDA__?path=\",\n      \"HttpRedirectCode\": \"307\"\n    }\n  }\n]\n```\n\u003e Pay attention to `__DOMAIN__` and `__PATH_TO_LAMBDA__` (protocol is always _https_)  \n\u003e This is your **API endpoint**. For example, if the url is `https://some-id.execute-api.us-east-1.amazonaws.com/your-stage/your-lambdas-name`, the correct xml nodes shall look like  \n```xml\n\u003cHostName\u003esome-id.execute-api.us-east-1.amazonaws.com\u003c/HostName\u003e\n\u003cReplaceKeyPrefixWith\u003eyour-stage/your-lambdas-name?path=\u003c/ReplaceKeyPrefixWith\u003e\n```\n* * At this state, before clicking on **Save**, copy your **Endpoint**. Do not mix it up. This is an endpoint of your Static website hosting, and it is http, not https.\n\n* Add `s3-resizer.zip` and make lambda work\n* * Go to your lambda and select Lambda layer (presumably, the API Gateway layer was selected instead)\n* * **Function code -\u003e Code entry type -\u003e Upload a .zip file** upload a zip file\n* * In **Runtime**, select the latest version of Node.js that you found on [Releases](https://github.com/sagidM/s3-resizer/releases)\n* * [You can now click on **Save** to save your time because it takes a while to upload a zip file]\n* * Set up the following **Environment variables** _(format: key=value)_  \n**BUCKET**=_your bucket's name_  \n**URL**=**Endpoint** you copied before (from Static website hosting)  \n**WHITELIST**=your list (space-separated) of allowed size options (e.g. AUTOx150 300x200 100x100_max). This parameter is optional, if not provided, the lambda will process everything  \n* * In **Basic settings**\n* * * Allocate 768mb memory\n* * * Timeout could be 5 seconds\n\u003e It's mooore than enough. But you shouldn't care of limits because images cache, which means the lambda is called only for the first time. For example, [large png 29mb image](http://www.berthiaumeescalier.com/images/contenu/file/Big__Small_Pumkins.png) converts to _150x150_ in 1.8s with 1024mb memory allocated, 2.3 with 768, 3.5 with 512mb, and ~7s with 256 on Node.js 12.13. _(I guess these such different results is because of [GC](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)))_. For normal images, results are nearly the same _(400-700 mls)_.\n* * **Save** it. You are done!\n\n***\n\n* Test your lambda (optional)\n* * Upload an image to your bucket and copy the full path to it. Check whether the image shows in your browser entering **\"ENDPOINT/FULL_PATH\"**\n\u003e Attention. **Endpoint**  is your Static website hosting (http). If you added the image to the root of your bucket, than **FULL_PATH** should be just a name of the image.\n* * Go to lambda, click on **Test**, and paste this json:\n```json\n{\n  \"queryStringParameters\": {\"path\": __YOUR_IMAGE_PATH_WITH_SIZE_PREFIX__}\n}\n```\n\u003e `__YOUR_IMAGE_PATH_WITH_SIZE_PREFIX__` - for example: `150x150/pretty_image.jpg`\n\n* * Go back to the bucket, a new directory _150x150_ must be created\n\n\n## How to use HTTPS\nThe Amazon S3 website endpoints do not support HTTPS  \nhttps://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html  \nAs a workaround, you have to use your own domain.  \nPlease check out https://github.com/sagidM/s3-resizer/issues/7  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FsagidM%2Fs3-resizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FsagidM%2Fs3-resizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FsagidM%2Fs3-resizer/lists"}