BartoNaz BartoNaz - 1 year ago 109
Python Question

Install node.js package over Python gear on Openshift

I have set up a Django application on the RedHat Openshift server with a single Python3.3 gear. For the front-end path of the application I need several tools: less, typescript, google-closure-compiler, which should be installed with the

npm install <package>

Unfortunately it doesn't seem to be possible, since execution of this command in the Openshift SSH console yields a permission error:

npm ERR! Error: EACCES, mkdir '/var/lib/openshift/572240982d5271a20c0000e2/.npm'
npm ERR! { [Error: EACCES, mkdir '/var/lib/openshift/572240982d5271a20c0000e2/.npm']
npm ERR! errno: 3,
npm ERR! code: 'EACCES',
npm ERR! path: '/var/lib/openshift/572240982d5271a20c0000e2/.npm' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

Fortunately I can install the google-closure-compiler by just downloading the compiled Java script, but for others there is no alternative installation method documented.

Is it possible to somehow install these packages for a Python app in Openshift so that the
compilers can be executed on the server during the build process?

Answer Source

Thanks to a very similar question that was asked before, I've figured out how to do this, although potentially not in the most optimal way. The procedure that worked for me is the following:

  1. Connect to your app via SSH and set the environment variable pointing to the location with dependencies:
    export DEPENDENCY_BASE="$OPENSHIFT_HOMEDIR/app-root/dependencies"
  2. Install the latest/desired version of node.js under $DEPENDENCY_BASE/node by downloading the Linux binary from the official web site, and extracting it:
    cd $DEPENDENCY_BASE; wget; tar -xf node-v4.4.3-linux-x64.tar.xz; mv node-v4.4.3-linux-x64 node; rm node-v4.4.3-linux-x64.tar.xz
  3. Create the following 2 folders for the locally installed npm manager:
    mkdir -p $DEPENDENCY_BASE/.npm $DEPENDENCY_BASE/node_modules/.bin
  4. Add the locally installed packages and node.js to the PATH so that they take precedence over the global ones:
    export PATH="$DEPENDENCY_BASE/node_modules/.bin/:$DEPENDENCY_BASE/node/bin/:$PATH"
  5. Execute node --version; npm --version to ensure that the new versions are used now
  6. Set the cache folder for npm to the one created in step 3, for which we have write permissions:
    npm config set cache "$DEPENDENCY_BASE/.npm"

Now every time a package has to be installed, the following command should be used:
npm install --prefix $DEPENDENCY_BASE <package name> [1]

It will install packages in the $DEPENDENCY_BASE/node_modules/ folder, while the corresponding binaries will be linked in the $DEPENDENCY_BASE/node_modules/.bin/ folder.

Apparently the same result can be achieved without installing a new version of node.js locally, but the installed npm version is rather old there, which is likely to lack certain features.

You can of course put commands 1 and 4 in the $OPENSHIFT_HOMEDIR/app-root/repo/.openshift/action_hooks/pre_build in order to use the command [1] for automatic deployment. Even better, instead of the command 1, set the global environment variable as described in the Openshift documentation.

If you want to use these commands interactively when connected via SSH, unfortunately the best way seems to be putting them in a bash script and running it manually. I couldn't find any working way to prepend the $PATH variable on login, since it is overwritten by the system afterwards.