David L. Rodgers
David L. Rodgers

Reputation: 1041

How can I create a "tmp" directory with Elastic Beanstalk?

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?

Upvotes: 10

Views: 6812

Answers (2)

timhj
timhj

Reputation: 517

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

Upvotes: 0

George Rushby
George Rushby

Reputation: 1345

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

Upvotes: 7

Related Questions