Rick Stanley
Rick Stanley

Reputation: 850

AWS CodeDeploy [stderr]/usr/bin/env: node: No such file or directory

When trying to run a script on AfterInstall event I receive:

LifecycleEvent - AfterInstall
Script - deploy/install_dependencies.sh
[stdout]Install dependencies. /
[stderr]/usr/bin/env: node: No such file or directory

, which is strange because:

  1. which node yields: ~/.nvm/versions/node/v15.2.0/bin/node
  2. which npm yields: ~/.nvm/versions/node/v15.2.0/bin/npm

The appspec.yml wasn't setup by me, but I think it's straightforward:

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/deploy/
permissions:
  - object: /
    pattern: "**"
    owner: ec2-user
hooks:
  AfterInstall:
    - location: deploy/install_dependencies.sh
    - location: deploy/build.sh
    - location: deploy/install_prd_dependencies.sh
    - location: deploy/copy_overwrite.sh
    # - location: deploy/migrations.sh
      timeout: 300
      runas: ec2-user
  ApplicationStart:
    - location: deploy/start_server.sh
      timeout: 300
      runas: ec2-user

I added runas: ec2-user and the permissions key with its values after reading this: Start Node Application in AfterInstall Hook , though not the same issue, it seemed that would solve my problem, but it didn't.

I checked if nvm was installed issuing which nvm, it didn't work:

[ec2-user@my-ip ~]$ which nvm
/usr/bin/which: no nvm in (/home/ec2-user/.nvm/versions/node/v15.2.0/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin)

but, issuing only nvm I recevie nvm's CLI help commands without any problem.

I checked the .bashrc of ec2-user to see if nvm was being exported correctly (as suggested in this answer):

# User specific aliases and functions

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

All scripts are using absolute path for npm/node binaries, examples:

install_dependencies.sh

#!/bin/bash

echo "Install dependencies. $(pwd)"
cd /home/ec2-user/deploy/

/home/ec2-user/.nvm/versions/node/v15.2.0/bin/npm install

start_server.sh

#!/bin/bash

echo "Restarting servers..."

/home/ec2-user/.nvm/versions/node/v15.2.0/bin/pm2 restart 0

Is codedpeloy using root user to issue these commands, even with runas setup for ec2-user? I don't understand what's happening, it worked before.

Upvotes: 4

Views: 1343

Answers (3)

Justin K
Justin K

Reputation: 31

TO Expand on Devin's answer, I added

source ~/.nvm/nvm.sh

to the beginning of my after_install.sh file and it did the trick.

This added the correct path to PM2 & NVM to the deployment user's path. You can confirm this by calling the following before and after the source command:

echo "$PATH"

Upvotes: 1

Devin
Devin

Reputation: 1992

This boils down to the path to node not available at the time of execution. If node is installed via nvm, try adding proper path.

Another way to do it is to add source ~/.nvm/nvm.sh to your bash profile (or an appropriate file, depending on your environment). See Node Version Manager install - nvm command not found

Upvotes: 1

Erma
Erma

Reputation: 71

I found that although CodeDeploy was running as the non-root user that I had set, it was not using the same environment variables as that user or that root was using on the command line. Try adding these lines into your script to debug:

echo `env`
echo `whoami`

I still don't know why that is. What I did was to export the path I needed before calling npm install in the script:

export PATH=$PATH:/correct/path

Upvotes: 0

Related Questions