How to Make Next.js Image Optimization Work on AWS Elastic Beanstalk
Tags: aws, javascript, nextjs, programming
Published: 2024-01-19 21:17:14

I recently worked on a large [Next.js](https://nextjs.org/) project and deployed it to [AWS Elastic Beanstalk](https://aws.amazon.com/elasticbeanstalk/). Everything worked fine, except for [Next.js image optimization](https://nextjs.org/docs/basic-features/image-optimization). Looking online for a workaround, I realized that this is quite a popular issue.

In fact, I read about many other developers who were having trouble getting the Next.js image optimization feature to work. Apparently, this is especially common when a platform other than Vercel is used to deploy a Next.js application.

Although it is popular, there is almost no documentation online. So, let's see how to address this issue and make image optimization work as expected when deploying Next.js to AWS Elastic Beanstalk.

## Diagnosing the Image Optimization Issue

To verify if the Next.js image optimization feature is working as expected, make sure to use the Next.js built-in [](https://nextjs.org/docs/api-reference/next/image) component instead of the standard HTML `<img>` tag. Keep in mind that [this feature is available only from Next.js 10](https://nextjs.org/blog/next-10#built-in-image-component-and-automatic-image-optimization).

Then, deploy your application to AWS Elastic Beanstalk.

Now, visit a web page containing at least one image rendered through the `<Image>` component and inspect it with your browser dev tools. You should be able to see something like this:

```html
<img alt="Foo image" src="/_next/image?url=https%3A%2F%2FyourCDN.com%2Ffoo.jpg&w=1920&q=75" decoding="async" data-nimg="intrinsic" style="position: absolute; inset: 0px; box-sizing: border-box; padding: 0px; border: none; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 100%;" srcset="/_next/image?url=https%3A%2F%2FyourCDN.com%2Ffoo.jpg&w=1080&q=75 1x, /_next/image?url=https%3A%2F%2FyourCDN.com%2Ffoo.jpg&w=1920&q=75 2x">
```

To make sure everything is working as expected, follow these steps:

1\. Build the transformed image URL by concatenating your website URL with the `<img>` ‘s `src` attribute, as follows:

```
https://yourwebsite.com/_next/image?url=https%3A%2F%2FyourCDN.com%2Ffoo.jpg&w=1920&q=75
```

2\. Extract the string contained in the `url` query parameter:

```
https%3A%2F%2FyourCDN.com%2Ffoo.jpg
```

3\. Decode it [here](https://meyerweb.com/eric/tools/dencoder/) to obtain the original image URL:

```
https://yourCDN.com/foo.jpg
```

4\. Compare the file of the image retrieved in step 1. with the file of the image retrieved in 3. If 1. is different from 3., then the Next.js image optimization feature is working as expected. Particularly, 1. should be in the [WebP](https://it.wikipedia.org/wiki/WebP) format (`.webp` extension) and significantly lighter than 3.

## Solving the Next.js Image Optimization Issue

Let's see the step-by-step guide on how to address the aforementioned issue with the Next.js image optimization feature when using AWS Elastic Beanstalk.

### 1\. Adding `sharp` to your project's dependencies

> When using `next start` in your production environment, it is strongly recommended that you install [`sharp`](https://www.npmjs.com/package/sharp) by running `yarn add sharp` in your project directory. This is not necessary for Vercel deployments, as `sharp` is installed automatically. — [next/image](https://nextjs.org/docs/basic-features/image-optimization)

As stated [in the official documentation](https://nextjs.org/docs/basic-features/image-optimization), the Next.js image optimization feature depends on the npm `sharp` library. But this is a Next.js [`optionalDependency`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#optionaldependencies) and it may not be installed. Consequently, you should explicitly add it to your project's dependencies with the following command:

```shell
npm install sharp
```

or the equivalent:

```shell
yarn add sharp
```

Now, while deploying your application to AWS Elastic Beanstalk, you may experience the following error message:

```
[`https://sharp.pixelplumbing.com/page/install`](https://sharp.pixelplumbing.com/page/install)
```

As explained [here](https://stackoverflow.com/questions/54996422/installing-sharp-on-elastic-beanstalk), the solution involves creating a `.npmrc` file containing the following line:unsafe-perm=true

In particular, by setting `unsafe-perm` to `true` you will force npm to attempt to always run within the context of the running script. In other words, this option forces the package installer to never switch the current user and group. So, in the case of AWS Elastic Beanstalk, this means that the npm install process will be executed as root. This prevents you from having any kind of problem with permissions and makes `sharp` installation flawless.

### 2\. Fixing `/var/app/current/build/cache/images` permissions

Installing `sharp` should be enough to solve the issue, but you may also encounter another problem. Specifically, if the image optimization feature is still not working, check the logs written by your Next.js app on AWS Elastic Beanstalk.

You might stumble across a message looking like this:

```
Dec 6 15:42:47 ip-VVV-XXX-YYY-ZZZ web: [Error: EACCES: permission denied, mkdir '/var/app/current/build/cache/images'] {  
Dec 6 15:42:47 ip-VVV-XXX-YYY-ZZZ web: errno: -13,  
Dec 6 15:42:47 ip-VVV-XXX-YYY-ZZZ web: code: 'EACCES',  
Dec 6 15:42:47 ip-VVV-XXX-YYY-ZZZ web: syscall: 'mkdir',  
Dec 6 15:42:47 ip-VVV-XXX-YYY-ZZZ web: path: '/var/app/current/build/cache/images'  
Dec 6 15:42:47 ip-VVV-XXX-YYY-ZZZ web: }  
  
  
  
  

```

This means that Next.js is trying to create a folder under `/var/app/current/build/cache/images` but it does not have the right permissions to do it. This is actually why the Next.js image optimization feature is not working. In fact, by delving into how it works, you will learn that it stores the generated transformed images into the `cache/images` folder inside `build`.

This is actually what the `build/cache/images` folder looks like on a fully working Next.js application.

![The build/cache/images folder when Next.js image optimization works](https://writech.run/wp-content/uploads/2023/08/image-103.png)

In other terms, to make the image optimization feature work, the Next.js application requires the read/write permission on the `build/cache/images` folder. To achieve this, create a bash `build.sh` file as follows:

```shell
#!/bin/bash

# Exit immediately if a command exits with a non-zero status
set -e

# deleting local.env.local to prevent Next.js from use it
rm -f ./.env.local

# building the Next.js application
npm run next:build

# creating the build/cache/images folder and give it
# the read/write permissions
mkdir -p build/cache/images
chmod -R 666 build/cache/images
```

Now, make sure that your `package.json` file contains the following "build" field under the "scripts" section:

```json
"scripts": {
  "build": "./build.sh"
}
```

When the `npm run build` command is executed, the `./build.sh` command will be launched and the `build.sh` script run as a result.

Et voilà! Your build script will now take care of creating the required `build/cache/images` folder with the right permissions. This should be enough to make the Next.js image optimization feature work as expected.

## Conclusion

The image optimization feature introduced in Next.js 10 represents a great improvement that allows you to build modern and fast websites. On the other hand, making it work as expected when deploying your application to platforms different from Vercel can become a challenge. This is particularly true when dealing with AWS Elastic Beanstalk. Luckily, there is a solution, and showing how to address the most common issues related to that feature was what this article was about.

Thanks for reading! I hope that you found this article helpful.
  
***
_The post "[How to Make Next.js Image Optimization Work on AWS Elastic Beanstalk](https://writech.run/blog/how-to-make-next-js-image-optimization-work-on-aws-elastic-beanstalk-2776ea255eff/)" appeared first on [Writech](https://writech.run)._