openstead
Guides

Deploy Node.js and Express

Deploy a Node.js API with a production start command and a reachable HTTP port.

Suggest a change

This guide uses Express, but the same web-service setup works for other Node.js HTTP frameworks when their production server binds to the configured port.

Prepare the server

For an ESM project with "type": "module" in package.json, a minimal server.js is:

import express from "express";

const app = express();
app.use(express.json());

app.get("/health", (_request, response) => {
  response.json({ status: "ok" });
});

app.get("/", (_request, response) => {
  response.json({ message: "Hello from Openstead" });
});

const port = Number(process.env.PORT || 3000);
const server = app.listen(port, "0.0.0.0");

process.on("SIGTERM", () => {
  server.close(() => process.exit(0));
});

For CommonJS, use require("express") instead of the import. Declare Express as a production dependency and commit the lockfile.

Add a production start script:

{
  "scripts": {
    "start": "node server.js"
  }
}

Merge this into the existing manifest rather than replacing its other fields.

Deploy the service

Create a Web Service from the repository:

SettingPlain JavaScriptCompiled TypeScript
Build methodRailpackRailpack
Build commandLeave empty if no build is neededYour build script, such as npm run build
Start commandnpm run startStart compiled output, such as node dist/server.js
Port30003000
Health check path/healthYour implemented health route

Ensure the build emits the path used by the start command. Development tools such as nodemon should not be the production process.

Connect a database

Create a managed database in the application's permitted private network and add its connection URL as a service variable. Use the database driver's connection pool, set sensible connection and query timeouts, and keep the total pool size within the database's limits as replicas increase.

Prisma, Sequelize, Knex, and similar tools need their own schema migration commands. Put the appropriate release migration in a paid pre-deploy command. Keep generated clients and production dependencies in the final artifact.

Connect a separate frontend

A browser-based frontend calls the API's public HTTPS URL. Configure CORS for the exact frontend origin and configure authentication cookies deliberately. A private database URL or private service hostname belongs only in backend code.

Troubleshooting

If the release never becomes ready, check 0.0.0.0, PORT, and the health path. If the runtime cannot find a module, confirm it is in production dependencies and was not omitted from the build. If an upload disappears after deployment, move it to a persistent disk or object storage.

Need a hand? Contact Openstead support.

On this page