Skip to main content
Version: 2.0.11

How to Deploy a Node.js App (Express, Next.js and More)

This guide shows how to host a Node.js application on OpenPanel - an Express API, a Next.js or Nuxt site, NestJS, or any other Node server. The app runs in its own Node.js container, and OpenPanel's web server forwards your domain to it with free SSL.

INFORMATION

Node.js applications are available in OpenPanel Enterprise, and the feature must be enabled for your hosting plan.


How It Works​

  • Your code lives in the domain folder, e.g. /var/www/html/example.com/.
  • OpenPanel runs an official node container with that folder as the working directory.
  • On every start it can run npm install, then your startup command.
  • The web server proxies https://example.com to the port your app listens on. WebSockets are supported.

Your app must listen on 0.0.0.0 (all interfaces), not 127.0.0.1.


Step 1: Add the Domain and Upload the Code​

  1. Add the domain in OpenPanel → Domains (Add a new domain).
  2. Upload the project to the domain folder with the File Manager or FTP - without node_modules/. Or deploy it from Git (below).

Step 2: Create the Application​

Go to OpenPanel → Websites → Install App → Setup Node.js Application and fill in:

FieldExpress exampleNext.js example
Nameapiweb
Domainapi.example.comexample.com
Port30003000
Startup Fileapp.jsserver.js (any .js file - the custom command is used)
Custom Startup Command(empty - runs node app.js)npm run build && npx next start -H 0.0.0.0 -p 3000
Versioncurrent LTS, e.g. 22current LTS, e.g. 22
Run Install✅ runs npm install✅ runs npm install
Git repositoryoptionaloptional
CPU / Memory0.5 / 0.5 GB1 / 2 GB (builds need memory)

Install Node.js Application form with the application details, domain, startup file and advanced options Install Node.js Application form with the application details, domain, startup file and advanced options

Click Start Installation, then open your domain.

Minimal Express app​

// app.js
const express = require("express");
const app = express();
const port = process.env.PORT || 3000;

app.get("/", (req, res) => res.send("Hello from Node.js on OpenPanel!"));

app.listen(port, "0.0.0.0", () => console.log(`Listening on ${port}`));

Other frameworks​

FrameworkCustom Startup Command
Next.jsnpm run build && npx next start -H 0.0.0.0 -p 3000
Nuxt 3npm run build && node .output/server/index.mjs (set PORT=3000, HOST=0.0.0.0 in .env)
NestJSnpm run build && node dist/main.js
Remix / React Routernpm run build && npm start
Static React / Vue / Vite buildNo Node app needed - build locally and upload dist/ as a static site
Faster restarts

Building on every start makes restarts slow. For large apps, build locally or in CI, upload the built output, and use only the start command (e.g. npx next start -H 0.0.0.0 -p 3000).


Deploy from Git​

Enter an https:// Git repository URL when creating the app. Every time the container starts, it fetches the latest commit of the default branch.

To deploy a new version: push to the repository, then Restart the app from its manage page. Only public repositories over https:// are supported.


Environment Variables​

Put settings and secrets in a .env file in the app folder and load them with dotenv (Next.js and Nuxt read .env automatically):

NODE_ENV=production
DATABASE_URL=mysql://dbuser:dbpass@mysql:3306/dbname

Restart the app after changing .env. Don't commit it to Git.


Databases and Redis​

Inside OpenPanel, services are reached by name - never localhost:

ServiceHostPort
MySQL / MariaDBmysql / mariadb3306
PostgreSQLpostgres5432
MongoDBmongodb27017
Redisredis6379

See connecting to MySQL from applications.


Managing the App​

In OpenPanel → Websites → Sites, click Manage next to the app to start, stop or restart it, view Logs (console.log output and errors), edit package.json and run npm under Install Packages, and change the Node version, startup command and CPU/memory limits under Overview.

Node.js application page with its status, runtime version, CPU and memory limits, and Stop and Restart actions Node.js application page with its status, runtime version, CPU and memory limits, and Stop and Restart actions

More: Node.js applications.


Troubleshooting​

ProblemFix
502 Bad GatewayThe app crashed or listens on a different port / on 127.0.0.1. Check Logs and match the Port field.
Cannot find moduleEnable Run Install, or make sure the dependency is in dependencies (not only devDependencies if you run npm install --production).
Build killed / JavaScript heap out of memoryIncrease the memory limit, or build outside the server.
Changes don't show upRestart the app - Node doesn't reload code automatically.