Deploy Node.js
Deploy a Node.js or Express application on Out Plane, with a managed database and migrations.
This guide deploys a Node.js application (Express or any HTTP server), connects it to a managed PostgreSQL database, and runs migrations. For the shared deploy flow, see Deploy from GitHub.
Prepare Your App
Listen on 0.0.0.0
Your app must bind 0.0.0.0 and the port you expose. Binding to localhost builds and
starts fine but is unreachable.
const port = process.env.PORT || 8080;
app.listen(port, '0.0.0.0', () => {
console.log(`listening on 0.0.0.0:${port}`);
});Reading PORT keeps the listen port and the exposed port in sync. You can also set PORT
yourself in environment variables.
Build and Start
| Step | Command |
|---|---|
| Build (JavaScript) | npm ci |
| Build (TypeScript) | npm ci && npm run build |
| Start | node server.js (or node dist/app.js after a TypeScript build) |
The start command runs as a direct exec, so node dist/app.js works as written. Wrap it
in sh -c "…" only when you need shell features. Pin your Node version with a package.json
engines field (for Buildpacks) or the base image tag (for a Dockerfile).
Deploy
Create an application from your repository. Out Plane uses your Dockerfile if present,
otherwise Buildpacks installs dependencies and runs your start script. Expose the port
your app listens on. A minimal Dockerfile:
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
CMD ["node", "server.js"]Connect a Database
Create a managed PostgreSQL database, then copy its connection
string into a DATABASE_URL environment variable.
Connections require SSL.
const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
ssl: { rejectUnauthorized: false },
});Prisma, Knex, Sequelize, and Drizzle all read DATABASE_URL automatically. If your
connection string does not already include it, append ?sslmode=require.
Run Migrations
Out Plane does not have a pre deploy hook, so run migrations one of two ways:
- Once, from the browser terminal: open a shell on a running
instance and run, for example,
npx prisma migrate deploy. - On every boot, from the start command:
sh -c "npx prisma migrate deploy && node server.js".
If you run more than one instance, every instance runs the boot migration. Use a tool that takes an advisory lock (Prisma, Knex) so concurrent runs are safe.
Environment Variables
- Set
NODE_ENV=production. It is not set by default, and it enables production behavior and caching. - Store
DATABASE_URLand your secrets as variables, or share them across apps with an Environment Variable Group.
Production Notes
- Bind
0.0.0.0, neverlocalhost. - Use
npm ci --omit=devand a plainnodeprocess. Do not shipnodemonorts-nodein production. - Persist uploads to a volume or object storage. The container filesystem is reset on every redeploy.