App Platform is a Platform-as-a-Service (PaaS) offering that allows developers to publish code directly to DigitalOcean servers without worrying about the underlying infrastructure.
App Platform supports two ways to build an image for your app: Cloud Native Buildpacks and Dockerfiles.
When you give App Platform access to your code, it defaults to using a Dockerfile if one is present in the root of the directory or specified in the app spec. Otherwise, App Platform checks your code to determine what language or framework it uses. If it supports the language or framework, it chooses an appropriate resource type and uses the proper buildpack to build the app and deploy a container.
App Platform uses the heroku-buildpack-nodejs buildpack for detecting and building your Node.js applications.
App Platform looks for any of the following files to detect a Node.js application:
package.json
package-lock.json
yarn.lock
pnpm-lock.yaml
If App Platform detects more than one package manager lockfile, it selects one to use during build time. The order of preference is yarn.lock
, pnpm-lock.yaml
, then package-lock.json
. If all three files are present, Yarn is preferred.
App Platform uses version 260
of the Heroku Node.js buildpack. The buildpack supports running most Node.js versions runtime versions (>= 0.10.0
) on the platform, but it is recommended to use the active LTS and Stable versions since these have higher test coverage.
The buildpack supports the following Node.js runtime versions:
App Platform uses Node.js 20.x
by default if you do not specify a Node.js version in the engines section.
You can specify your desired Node.js version in the engines
section of package.json
.
{
"engines": {
"node": "16.x"
}
}
App Platform supports npm, Yarn, and pnpm to build the Node.js applications.
We recommend using only one package manager in your application to avoid any conflicts.
If you have a package-lock.json
or package.json
at the root of your application, App Platform uses the npm
package manager.
App Platform defaults to installing the current version of npm
as designated by the Node.js release. You can customize the npm
version used by specifying the version in the engines
section of your package.json
:
{
"engines": {
"npm": "~1.0.20"
}
}
If you have yarn.lock
at the root of your application along with package.json
, App Platform uses yarn
to build your application. You can specify the yarn
version in packageManager
section of your package.json
, like this:
{
"packageManager": "[email protected]"
}
This method uses Corepack which is preferred for Yarn tooling. The version defined in package.json
must be exact, but can be configured from a version range with Corepack’s use command, for example, corepack use [email protected]
.
You can also specify a yarn
version in the engines
section of your package.json
:
{
"engines": {
"yarn": "^0.14.0"
}
}
If you have pnpm-lock.yaml
at the root of your application along with package.json
, App Platform uses pnpm
to build your application. You can specify which pnpm
version in the packageManager
section of your package.json
, like this:
{
"packageManager": "[email protected]"
}
This method uses Corepack, which is preferred for pnpm tooling. The version defined in package.json
must be exact, but you can configure a version range with Corepack’s use command, for example, corepack use [email protected]
.
You can also specify a pnpm
version in the engines
section of your package.json
, like this:
{
"engines": {
"pnpm": "9.0.5"
}
}
App Platform uses the same build process regardless of the package manager used. All the dependencies listed in package.json
under dependencies
and devDependencies
are installed by default. However, after the build steps, the packages declared under devDependencies
are stripped before application deployment.
package-lock.json
, pnpm-lock.yaml
, or yarn.lock
) to your repository and keep them updated. This ensures that the dependencies are installed correctly.If you use npm
, it uses npm ci
to set up the build environment.
If you prefer to use npm install
instead of npm ci
, set the USE_NPM_INSTALL
environment variable with a BUILD_TIME
scope in your app’s spec, like this:
services:
- name: web
git:
repo: "https://github.com/example/repo"
branch: master
envs:
- key: USE_NPM_INSTALL
scope: BUILD_TIME
value: "true"
If you don’t use npm
or you don’t want to cache Node_modules
, declare a NODE_MODULES_CACHE
environment variable in your app spec and set it to false
, like this:
services:
- name: web
git:
repo: "https://github.com/example/repo"
branch: master
envs:
- key: NODE_MODULES_CACHE
scope: BUILD_TIME
value: false
To disable the installation of devDependencies
, set these environment set NPM_CONFIG_PRODUCTION
to true
if you are using npm, or YARN_PRODUCTION
to true
if you are using yarn, like this:
services:
- name: web
git:
repo: "https://github.com/example/repo"
branch: master
envs:
- key: NPM_CONFIG_PRODUCTION
scope: BUILD_TIME
value: true
The build process prunes the devDependencies
before application deployment. If you want to keep these devDependencies
, skip the pruning step by:
NODE_ENV
to anything other than production
. This works for all the package managers.NPM_CONFIG_PRODUCTION=false
if you’re using npm.PNPM_SKIP_PRUNING=true
if you’re using pnpm.YARN_PRODUCTION=false
if you’re using Yarn v1.YARN2_SKIP_PRUNING=true
if you’re using Yarn v2 and above.By default, the build
script in package.json
is used to build the application.
While each package manager supports standard preinstall
and postinstall
scripts, you can run scripts only before or after other build steps. To run specific actions before or after installing dependencies, use the heroku-prebuild
, heroku-postbuild
, and heroku-cleanup
scripts.
"scripts": {
"heroku-prebuild": "echo This runs before installing dependencies.",
"heroku-postbuild": "echo This runs after installing dependencies, but before pruning and caching dependencies.",
"heroku-cleanup": "echo This runs after pruning and caching dependencies."
}
You can set build flags to your build
script by setting NODE_BUILD_FLAGS
environment variable.
You can configure npm
by:
.npmrc
file in the root directory.NPM_CONFIG
environment variable. npm
reads configuration from any environment variables beginning with NPM_CONFIG
.When NPM_CONFIG_PRODUCTION
is set to true
, npm automatically runs all scripts in a subshell where NODE_ENV
is production
.
You can use private packages with npm
by configuring the private registry and access token. If the app uses a private dependency source, such a Gemfury, the project must configure an alternate registry with access tokens.
You can specify registry URL and authorization token in .npmrc
, like this:
@scope:registry=https://registry.npmjs.org
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
In this example, NPM_TOKEN
is provided as environment variable.
It maintains a build cache that stores caches for npm
, yarn
, and bower
that persists between builds.
You can disable all caching by setting NODE_MODULES_CACHE=false
environment variable.
The node_modules
and bower_components
are cached by default.
You can override these defaults by setting cacheDirectories
array in package.json
.
"cacheDirectories": ["client/node_modules", "server/node_modules", "data"]
If your app is failing to build and you suspect that the issue is related to node_modules
caching, you can force clear the cache and start a new build. To do this in the control panel, navigate to your app, click the Actions menu, and then select Force Build and Deploy.
In the Force Build and Deploy window, select the Clear Build Cache option, and then click on the Deploy button. This clears the build cache and starts a new deployment.
Here’s an example with Node and Express that uses the PORT
variable or 3000
for developing locally.
const express = require('express');
const app = express();
// get our port
const port = process.env.PORT || 3000;
// application code goes here
// have node listen on our port
app.listen(port, () => console.log(`App listening on port ${port}!`));