10

I'm using Node.js and need to save files to a tmp directory within my app. The problem is that Elastic Beanstalk does not set the app directory to be writable by the app. So when I try to create the temp directory I get this error

fs.js:653
  return binding.mkdir(pathModule._makeLong(path),
                 ^
Error: EACCES, permission denied '/var/app/tmp/'
    at Object.fs.mkdirSync (fs.js:653:18)
    at Promise.<anonymous> (/var/app/current/routes/auth.js:116:18)
    at Promise.<anonymous> (/var/app/current/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8)
    at Promise.emit (events.js:95:17)
    at Promise.emit (/var/app/current/node_modules/mongoose/node_modules/mpromise/lib/promise.js:84:38)
    at Promise.fulfill (/var/app/current/node_modules/mongoose/node_modules/mpromise/lib/promise.js:97:20)
    at /var/app/current/node_modules/mongoose/lib/query.js:1394:13
    at model.Document.init (/var/app/current/node_modules/mongoose/lib/document.js:250:11)
    at completeOne (/var/app/current/node_modules/mongoose/lib/query.js:1392:10)
    at Object.cb (/var/app/current/node_modules/mongoose/lib/query.js:1151:11)

I've tried several things such as an app-setup.sh script within .ebextensions/scripts/app-setup.sh that looks like this

#!/bin/bash

# Check if this is the very first time that this script is running
if ([ ! -f /root/.not-a-new-instance.txt ]) then
    newEC2Instance=true
fi



# Get the directory of 'this' script
dirCurScript=$(dirname "${BASH_SOURCE[0]}")

# Fix the line endings of all files
find $dirCurScript/../../ -type f | xargs dos2unix -q -k

# Get the app configuration environment variables
source $dirCurScript/../../copy-to-slash/root/.elastic-beanstalk-app
export ELASTICBEANSTALK_APP_DIR="/$ELASTICBEANSTALK_APP_NAME"

appName="$ELASTICBEANSTALK_APP_NAME"
dirApp="$ELASTICBEANSTALK_APP_DIR"

dirAppExt="$ELASTICBEANSTALK_APP_DIR/.ebextensions"
dirAppTmp="$ELASTICBEANSTALK_APP_DIR/tmp"

dirAppData="$dirAppExt/data"
dirAppScript="$dirAppExt/scripts"


# Create tmp directory
mkdir -p $dirApp/tmp

# Set permissions
chmod 777 $dirApp
chmod 777 $dirApp/tmp

# Ensuring all the required environment settings after all the above setup
if ([ -f ~/.bash_profile ]) then
    source ~/.bash_profile
fi

# If new instance, now it is not new anymore
if ([ $newEC2Instance ]) then
    echo -n "" > /root/.not-a-new-instance.txt
fi


# Print the finish time of this script
echo $(date)


# Always successful exit so that beanstalk does not stop creating the environment
exit 0

As well as creating a file called 02_env.config within .ebextensions that looks like this

# .ebextensions/99datadog.config
    container_commands:
        01mkdir:
            command: "mkdir /var/app/tmp"
        02chmod:
            command: "chmod 777 /var/app/tmp"

Neither seem to work. How can I create a tmp directory within my app that is writable?

David L. Rodgers
  • 1,031
  • 1
  • 8
  • 18

2 Answers2

7

I recently experienced the same issue with a .NET application where the application was failing because it couldn't write to a directory, even after I had set the permissions.

What I found was that after the whole .ebextensions process was completed, the final step was a web container permissions update which ended up overwriting my ebextensions permissions change.

To solve it I moved the directory outside of the web container and updated the application to write there instead.

In your case I would suggest /tmp

Mohamed Taher Alrefaie
  • 15,698
  • 9
  • 48
  • 66
George Rushby
  • 1,305
  • 8
  • 13
  • This helped me a ton! I'm hesitant to mark it as the accepted answer as it doesn't actually solve the problem (being able to write to the app directory should be possible) but if no other answers are provided I'll give you the credit. – David L. Rodgers Jan 16 '15 at 10:49
0

With the newer (current?) Amazon Linux 2 elastic beanstalk installs, setting up a Post Deploy hook is the way to make this happen. The tmp folder needs to be created and made writeable AFTER elastic beanstalk has moved the newly deployed app bundle to /var/app. It's just a shell script placed in the following location from the root of your app:

.platform/hooks/postdeploy/10_create_tmp_and_make_writeable.sh

#!/bin/bash
mkdir /var/app/current/tmp
chmod 777 /var/app/current/tmp
timhj
  • 497
  • 4
  • 14
  • So what exactly need to be done to fix permission problem? – Victor Nikitin Sep 14 '21 at 20:00
  • @VictorNikitin - If you're deploying to an amazon linux 2 based instance of Elastic Beanstalk, add a file to the root of your project at .platform/hooks/postdeploy/10_create_tmp_and_make_writeable.sh with the three line script above. – timhj Sep 15 '21 at 05:33
  • previously this path for hook was "/opt/elasticbeanstalk/hooks/appdeploy/post/filename.sh". We will try you advice. Thanks. – Victor Nikitin Sep 16 '21 at 13:19
  • Hook runs ok, but script "chmod -R 777 /var/app/current/" failed with "permission denied". How it is possible to allow application to write into app folder? – Victor Nikitin Sep 16 '21 at 18:48
  • @VictorNikitin - I'm not sure you can recursively make the whole app directory 777. Can you try doing it for a tmp subdirectory in the app dir? like this: Try the script as ```sudo mkdir /var/app/current/tmp sudo chmod 777 /var/app/current/tmp``` – timhj Sep 17 '21 at 03:48
  • The problem was because we created subfolders during deploy in our scripts (not aws hooks). In some reason this subfolders did not have permissions. We do not understand why posthook did not chmod them. May be posthook ran before our deploy script. So we added "chmod" in our deploy scripts. – Victor Nikitin Sep 21 '21 at 07:10