Overview
By default, Upsun environments include a specific version of Node.js tailored to the runtime image you are using. However, certain applications, such as Ruby on Rails 6 using Webpacker, may require a more recent version of Node.js than what is provided in the default Ruby image.
This article explains how to use a version manager (like nvm or n) to install and use a specific Node.js version within your application container.
Solution: Using a Node Version Manager
When your application's type is not nodejs (for example, type: 'ruby:3.0'), you cannot simply change the type to update Node. Instead, you must install the desired version during the build process.
1. Define your desired version
You can specify your required Node.js version in your repository using one of the following standard files:
.nvmrc: Contains just the version number (e.g.,
16.13.2).node-version: Contains the version number (e.g.,
18.14.2)package.json: Using the
enginesproperty (e.g.,"node": ">=16")
2. Configure Environment Variables
Update your .upsun/config.yaml to define the version of the manager and the Node version you wish to use.
YAML
applications:
myapp:
type: 'ruby:3.0' # Example for a Rails app
variables:
env:
NVM_VERSION: v0.39.3
NODE_VERSION: v18.14.2 # Or your required version
3. Install Node.js in the Build Hook
To ensure the custom Node version is available during the build (for tasks like rails assets:precompile) and at runtime, you must install it in the build hook.
Using a symlink to the cache directory ensures that Node.js doesn't have to be re-downloaded on every deployment, which keeps your builds fast.
YAML
applications:
myapp:
# ... (other config)
hooks:
build: |
set -e
# Install NVM and the specific Node version
unset NPM_CONFIG_PREFIX
export NVM_DIR="$UPSUN_APP_DIR/.nvm"
# Link cache with app to persist the installation
if [ ! -d "$UPSUN_CACHE_DIR/.nvm" ]; then
mkdir -p "$UPSUN_CACHE_DIR/.nvm"
fi
ln -s "$UPSUN_CACHE_DIR/.nvm" "$NVM_DIR"
# Download and install NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/$NVM_VERSION/install.sh | bash
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Install the requested Node version
nvm install $NODE_VERSION
nvm use $NODE_VERSION
# Now proceed with your app's build (e.g., Webpacker/Sprockets)
bundle install
yarn install
bundle exec rails assets:precompile
4. Ensure Node is available at Runtime
Because the build hook environment is separate from the runtime environment, you must ensure your application can find the new Node binary. The best way to do this is to use a .environment file to export the path.
Create a .environment file in your app root:
Bash
export NVM_DIR="$UPSUN_APP_DIR/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm use $NODE_VERSION --silent
Why this is necessary for Rails/Webpacker
Legacy versions of Webpacker often have dependencies on newer Node.js features or specific Node APIs that are not present in the default Node.js version bundled with older Ruby images. By using the method above, you decouple your Node.js requirements from the base Ruby image, allowing you to satisfy Webpacker's requirements without waiting for a global image update.
For further details, refer to the Official Upsun Node.js Version Management Guide.
Comments
Please sign in to leave a comment.