Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Installing Sharp on Elastic Beanstalk

I'm rather new to AWS. I'm running a Node.JS app on Elastic Beanstalk, and everything was working fine. However, because I need to do some image processing I decided to add Puppeteer and Sharp.

However, the installation on AWS fails and the application crashes. The log says the following:

  [email protected] install /tmp/deployment/application/node_modules/sharp
 (node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)

  ERR! sharp EACCES: permission denied, mkdir '/tmp/.npm/_libvips'
  info sharp Attempting to build from source via node-gyp but this may fail due to the above error
  info sharp Please see https://sharp.pixelplumbing.com/page/install for required dependencies
  gyp ERR! configure error 
  gyp ERR! stack Error: EACCES: permission denied, mkdir '/tmp/deployment/application/node_modules/sharp/build'
  gyp ERR! System Linux 4.14.97-74.72.amzn1.x86_64
  gyp ERR! command "/opt/elasticbeanstalk/node-install/node-v10.15.1-linux-x64/bin/node" "/opt/elasticbeanstalk/node-install/node-v10.15.1-linux-x64/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
  gyp ERR! cwd /tmp/deployment/application/node_modules/sharp
  gyp ERR! node -v v10.15.1
  gyp ERR! node-gyp -v v3.8.0
  gyp ERR! not ok 
  npm ERR! code ELIFECYCLE
  npm ERR! errno 1
  npm ERR! [email protected] install: `(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)`
  npm ERR! Exit status 1
  npm ERR! 
  npm ERR! Failed at the [email protected] install script.
  npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

I'm really not familiar with Elastic Beanstalk, but that seems like an access restriction error. After searching for a bit, I found a possible solution: Adding the following code as an .extension file.

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/00_set_tmp_permissions.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      chown -R nodejs:nodejs /tmp/.npm

However, that didn't seem to do anything. Does anybody know where the error could be? Or where I should look for a solution? I'm not usually at home with this kind of stuff, but I'm forced to work with it for a while. Any help and advice would be greatly appreciated!

like image 702
NielsJ Avatar asked Mar 05 '19 06:03

NielsJ


2 Answers

This is permission issues with AWS.

To solve this you have to follow the next steps:

  1. Create a new file .npmrc
  2. Add the following unsafe-perm=true

This will let to write files.

like image 71
Mihai Zhao Avatar answered Oct 29 '22 21:10

Mihai Zhao


unsafe-perm=true is not working anymore with Node 16 and Amazon Linux 2, because it can't install the Sharp package. I was trying to install Strapi v4 on Elastic Beanstalk.

You need to perform permission updates in platform hooks according to this answer: https://github.com/lovell/sharp/issues/3221#issuecomment-1126528844

You can find additonal information to platform hooks here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html

You don't need to do anything about the execute permissions when your Amazon Linux 2 was released after April 29, 2022.


Solution: Step 1: Create the following Platform Hooks paths in the root directory of your application bundle.

-  .platform/hooks/prebuild
-  .platform/confighooks/prebuild

The Platform Hook (.platform/hooks/prebuild) will execute the commands found in the bash script after the application is extracted but before the application configuration and proxy server process initiates.

The Platform Hook (.platform/confighooks/prebuild) will execute the commands found in the bash script during a configuration deployment/environment update.


Step 2: Once the above Platform Hooks paths have been created in your application bundle, the following bash script (00_npm_install.sh) will need to be created and placed under the "Prebuild" directory:

The bash script (00_npm_install.sh) will include the following:

#!/bin/bash
cd /var/app/staging
sudo -u webapp npm install sharp

Step 3: Validate the Application Bundle Structure

Sample project structure:

~/my-app/
├── app.js
├── index.html
├── .npmrc_bkp
├── package.json
├── package-lock.json
├── .platform
│   ├── confighooks
│   │   └── prebuild
│   │       └── 00_npm_install.sh
│   └── hooks
│       └── prebuild
│           └── 00_npm_install.sh
└── Procfile

Step 4: Deploy the Application!


Summary:

During the application deployment process, the application bundle is initially extracted and deployed within the /var/app/staging folder. In this same first step, all Node.js dependencies found in your (package.json) file will also be installed here but exist under /var/app/staging/node_modules/....

As mentioned in your comment, the /var/app/staging folder is owned by the webapp user but the npm install command is executed by root user. Therefore, the bash script workaround solution goes to the /var/app/staging/ directory and install the Sharp dependency by executing the sudo -u webapp npm install sharp command as the webapp user. All of this is done before the application and proxy server configuration process initiates as shown in "Instance deployment workflow".

As a result, the workaround solution will make the Elastic Beanstalk deployment process skip installing the Sharp dependency all together as it already exists! Afterwards, the application deployment process continues to the final provisioning step which moves all files/content from the /var/app/staging/ folder to the final /var/app/current/ directory location.

Lastly, the second Platform Hook (.platform/confighooks/prebuild) was implemented to avoid running into the same permissions error when performing a configuration deployment. A configuration deployment occurs when you make configuration changes that only update environment instances without recreating them!

Hope the following solution helps!

like image 42
NKol Avatar answered Oct 29 '22 22:10

NKol