Tutorials

How to Deploy a Node.js App on DeployBase: The Complete Guide

Muhammad SaadApril 17, 202612 min read
How to Deploy a Node.js App on DeployBase: The Complete Guide

Node.js has become the go-to runtime for building fast, scalable web applications — from REST APIs and real-time chat apps to full-stack applications with frameworks like Express, Fastify, and Next.js. But finding the right Node.js hosting that does not force you into complex server administration is harder than it should be.

This step-by-step guide walks you through deploying a Node.js application on DeployBase, from initial setup to connecting databases, configuring your domain, and keeping your app running in production. Whether you are deploying your first Express API or migrating an existing project, this tutorial covers everything you need.

Why DeployBase for Node.js Hosting?

Most traditional hosting providers treat Node.js as an afterthought — requiring you to buy VPS plans and configure everything from scratch. DeployBase offers Node.js hosting as a first-class feature:

  • One-click Node.js setup — Select Node.js as your application type and DeployBase provisions your hosting environment automatically. No manual server configuration.
  • SSH access on all plans — Full terminal access to install npm packages, run scripts, manage processes, and debug your application.
  • MySQL, PostgreSQL, and Redis — Connect your Node.js app to the database it needs. PostgreSQL for relational data, Redis for caching and session storage — all available from the dashboard.
  • Free SSL certificates — Every application gets HTTPS automatically. Essential for APIs and web apps handling user data.
  • Custom domain support — Connect your own domain to your Node.js application.
  • Built-in file manager — Upload and manage files through the browser when SSH is not convenient.

Step 1: Prepare Your Node.js Application

Before deploying, make sure your application is production-ready. Here is a checklist:

package.json Essentials

Your package.json should include a start script and specify the Node.js engine version:

{
  "name": "my-node-app",
  "version": "1.0.0",
  "engines": {
    "node": ">=18.0.0"
  },
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js"
  },
  "dependencies": {
    "express": "^4.18.0",
    "dotenv": "^16.0.0"
  }
}

Environment Variables

Never hardcode sensitive values like database credentials or API keys. Use environment variables:

// server.js
require('dotenv').config();

const express = require('express');
const app = express();

const PORT = process.env.PORT || 3000;
const DB_URL = process.env.DATABASE_URL;

app.get('/', (req, res) => {
  res.json({ status: 'ok', message: 'App is running' });
});

app.get('/health', (req, res) => {
  res.json({
    status: 'healthy',
    uptime: process.uptime(),
    timestamp: new Date().toISOString()
  });
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Create a .gitignore

If you are using Git to manage your project (which you should), make sure sensitive files are excluded:

# .gitignore
node_modules/
.env
*.log
dist/
.DS_Store

Step 2: Create Your Node.js App on DeployBase

Log in to your DeployBase dashboard and create a new hosting instance. Select Node.js as your application type.

DeployBase will provision your hosting environment with Node.js pre-installed. Once the setup completes, you will have:

  • A running Node.js environment
  • SSH credentials to access your server
  • A default URL where your app will be accessible

Step 3: Deploy Your Code via SSH

With SSH access on all DeployBase plans, you can deploy your Node.js application directly from the terminal.

Connect to Your Server

# SSH into your DeployBase application
ssh your-user@your-app.deploybase.io

Upload Your Project

You have several options to get your code onto the server:

Option A: Clone from GitHub

If your code is in a GitHub repository, clone it directly on the server. This is the recommended approach for web hosting GitHub workflows — keeping your deployment tied to your version control:

# Clone your repository
git clone https://github.com/yourusername/your-node-app.git
cd your-node-app

# Install production dependencies
npm ci --production

To update your app later, simply pull the latest changes:

# Pull latest code from GitHub and restart
cd your-node-app
git pull origin main
npm ci --production
pm2 restart app

Option B: Upload via SCP

If your project is not on GitHub, upload files directly using SCP:

# From your local machine
scp -r ./my-node-app your-user@your-app.deploybase.io:~/

# Then SSH in and install dependencies
ssh your-user@your-app.deploybase.io
cd my-node-app
npm ci --production

Option C: Use the File Manager

DeployBase includes a built-in file manager in the dashboard. You can upload a zipped project archive, extract it on the server, and then install dependencies via SSH.

Step 4: Set Up Environment Variables

Your Node.js application likely needs environment variables for database connections, API keys, and configuration. Create a .env file on the server:

# SSH into your server
ssh your-user@your-app.deploybase.io
cd your-node-app

# Create your .env file
nano .env

Add your configuration:

# .env
NODE_ENV=production
PORT=3000
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
REDIS_URL=redis://localhost:6379
SESSION_SECRET=your-random-secret-string
API_KEY=your-api-key

Make sure your application reads these using the dotenv package (or your framework's built-in environment handling).

Step 5: Run Your App with a Process Manager

Running node server.js directly will stop your app when your SSH session ends. Use PM2 — the standard Node.js process manager — to keep your application running reliably:

Install and Configure PM2

# Install PM2 globally
npm install -g pm2

# Start your application
pm2 start server.js --name "my-app"

# Or start with environment file
pm2 start server.js --name "my-app" --env production

# Save the process list so PM2 restarts your app on server reboot
pm2 save
pm2 startup

Essential PM2 Commands

# View running processes
pm2 list

# View real-time logs
pm2 logs my-app

# View last 100 log lines
pm2 logs my-app --lines 100

# Monitor CPU and memory usage
pm2 monit

# Restart your app (after code changes)
pm2 restart my-app

# Graceful restart (cluster mode)
pm2 reload my-app

# Stop your app
pm2 stop my-app

# View detailed app info
pm2 show my-app

PM2 Ecosystem File (Optional)

For more complex configurations, create an ecosystem.config.js file:

// ecosystem.config.js
module.exports = {
  apps: [{
    name: 'my-app',
    script: 'server.js',
    instances: 'max',      // Use all CPU cores
    exec_mode: 'cluster',  // Enable cluster mode
    env_production: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    max_memory_restart: '256M',
    log_date_format: 'YYYY-MM-DD HH:mm:ss',
    error_file: './logs/error.log',
    out_file: './logs/output.log'
  }]
};

// Start with: pm2 start ecosystem.config.js --env production

Step 6: Connect a Database

Most Node.js applications need a database. DeployBase supports MySQL, PostgreSQL, and Redis — provision any of them from the dashboard.

PostgreSQL with Node.js

PostgreSQL is an excellent choice for Node.js apps that need relational data, JSON columns, or complex queries. Provision a PostgreSQL database from your DeployBase dashboard, then connect using the pg package:

npm install pg
// db.js — PostgreSQL connection
const { Pool } = require('pg');

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: process.env.NODE_ENV === 'production'
    ? { rejectUnauthorized: false }
    : false
});

// Test the connection
pool.query('SELECT NOW()', (err, res) => {
  if (err) {
    console.error('Database connection failed:', err.message);
  } else {
    console.log('Connected to PostgreSQL at:', res.rows[0].now);
  }
});

module.exports = pool;

MySQL with Node.js

If your application uses MySQL, provision a MySQL database and connect with mysql2:

npm install mysql2
// db.js — MySQL connection
const mysql = require('mysql2/promise');

const pool = mysql.createPool({
  host: process.env.DB_HOST,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  waitForConnections: true,
  connectionLimit: 10
});

// Test the connection
async function testConnection() {
  try {
    const [rows] = await pool.query('SELECT 1');
    console.log('Connected to MySQL');
  } catch (err) {
    console.error('MySQL connection failed:', err.message);
  }
}

testConnection();
module.exports = pool;

Redis for Caching and Sessions

Redis is ideal for caching API responses, storing sessions, and managing rate limiting. Provision Redis from your DeployBase dashboard, then connect:

npm install ioredis
// cache.js — Redis connection
const Redis = require('ioredis');

const redis = new Redis(process.env.REDIS_URL);

redis.on('connect', () => console.log('Connected to Redis'));
redis.on('error', (err) => console.error('Redis error:', err.message));

// Example: Cache an API response for 5 minutes
async function cacheMiddleware(req, res, next) {
  const key = `cache:${req.originalUrl}`;
  const cached = await redis.get(key);

  if (cached) {
    return res.json(JSON.parse(cached));
  }

  // Store original json method
  const originalJson = res.json.bind(res);
  res.json = (body) => {
    redis.setex(key, 300, JSON.stringify(body)); // Cache for 300 seconds
    return originalJson(body);
  };

  next();
}

module.exports = { redis, cacheMiddleware };

Using Redis for Session Storage

npm install express-session connect-redis
const session = require('express-session');
const RedisStore = require('connect-redis').default;
const Redis = require('ioredis');

const redisClient = new Redis(process.env.REDIS_URL);

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: process.env.NODE_ENV === 'production',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000 // 24 hours
  }
}));

Step 7: Connect Your Custom Domain

Your Node.js app starts on a default DeployBase URL. Connect your own domain for production use.

DNS Configuration

In your domain registrar's DNS settings, add these records:

# A record for root domain
Type: A
Name: @
Value: [Your DeployBase IP from the dashboard]
TTL: 3600

# CNAME for www subdomain
Type: CNAME
Name: www
Value: your-app.deploybase.io
TTL: 3600

Update Your Application

If your app uses CORS, allowed origins, or similar domain-specific configuration, update those settings to include your custom domain:

const cors = require('cors');

app.use(cors({
  origin: [
    'https://yourdomain.com',
    'https://www.yourdomain.com'
  ],
  credentials: true
}));

Step 8: Set Up Free SSL

DeployBase includes free SSL certificates on all plans. Once your custom domain's DNS is pointing to your DeployBase application, SSL is provisioned automatically.

Make sure your Node.js application trusts the proxy headers for proper HTTPS detection:

// Trust proxy headers (important when behind a reverse proxy)
app.set('trust proxy', 1);

// Redirect HTTP to HTTPS in production
if (process.env.NODE_ENV === 'production') {
  app.use((req, res, next) => {
    if (req.headers['x-forwarded-proto'] !== 'https') {
      return res.redirect(301, `https://${req.hostname}${req.url}`);
    }
    next();
  });
}

Step 9: Production Hardening

Before your Node.js app handles real traffic, apply these production best practices:

Security Middleware

npm install helmet express-rate-limit
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');

// Set security headers
app.use(helmet());

// Rate limiting — prevent abuse
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // Limit each IP to 100 requests per window
  standardHeaders: true,
  legacyHeaders: false,
  message: { error: 'Too many requests, please try again later.' }
});
app.use('/api/', limiter);

Error Handling

// Global error handler — never expose stack traces in production
app.use((err, req, res, next) => {
  console.error('Unhandled error:', err);

  const status = err.status || 500;
  const message = process.env.NODE_ENV === 'production'
    ? 'Internal server error'
    : err.message;

  res.status(status).json({ error: message });
});

// Handle unhandled promise rejections
process.on('unhandledRejection', (reason, promise) => {
  console.error('Unhandled rejection at:', promise, 'reason:', reason);
});

// Handle uncaught exceptions
process.on('uncaughtException', (err) => {
  console.error('Uncaught exception:', err);
  process.exit(1); // PM2 will restart the process
});

Logging

npm install morgan
const morgan = require('morgan');
const fs = require('fs');
const path = require('path');

// Log to file in production, console in development
if (process.env.NODE_ENV === 'production') {
  const accessLog = fs.createWriteStream(
    path.join(__dirname, 'logs', 'access.log'),
    { flags: 'a' }
  );
  app.use(morgan('combined', { stream: accessLog }));
} else {
  app.use(morgan('dev'));
}

Step 10: Updating Your Application

When you push updates to your code, here is the deployment workflow:

If Using GitHub

# SSH into your server
ssh your-user@your-app.deploybase.io
cd your-node-app

# Pull latest changes
git pull origin main

# Install any new dependencies
npm ci --production

# Run database migrations (if applicable)
npm run migrate

# Restart the application
pm2 restart my-app

# Check logs to verify everything is working
pm2 logs my-app --lines 20

Quick Deploy Script

Save time with a deploy script you can run from your local machine:

#!/bin/bash
# deploy.sh — Run from your local machine
HOST="your-user@your-app.deploybase.io"
APP_DIR="~/your-node-app"

echo "Deploying to DeployBase..."

ssh $HOST "cd $APP_DIR && \
  git pull origin main && \
  npm ci --production && \
  pm2 restart my-app"

echo "Deploy complete. Checking status..."
ssh $HOST "pm2 list"
# Make it executable and run
chmod +x deploy.sh
./deploy.sh

Monitoring and Debugging

Keep an eye on your running application with these commands over SSH:

# View real-time logs
pm2 logs my-app

# Monitor CPU and memory
pm2 monit

# Check application status
pm2 show my-app

# Check disk usage
df -h

# Check Node.js version
node --version

# Check running processes
pm2 list

# View error logs only
pm2 logs my-app --err --lines 50

Common Issues and Solutions

App Crashes on Start

# Check the error logs
pm2 logs my-app --err --lines 50

# Common causes:
# 1. Missing environment variables — check your .env file
# 2. Port already in use — make sure PORT matches your config
# 3. Missing dependencies — run npm ci --production
# 4. Syntax errors — check the error message for file and line number

Cannot Connect to Database

# Test PostgreSQL connection
psql $DATABASE_URL -c "SELECT 1;"

# Test MySQL connection
mysql -u $DB_USER -p -h $DB_HOST $DB_NAME -e "SELECT 1;"

# Test Redis connection
redis-cli -u $REDIS_URL ping

# Common causes:
# 1. Wrong credentials in .env
# 2. Database not provisioned yet — check DeployBase dashboard
# 3. Firewall blocking the connection

App Runs Locally but Not on Server

# Check Node.js version matches
node --version

# Check if all dependencies are installed
npm ci --production

# Check if the PORT environment variable is set correctly
echo $PORT

# Make sure your app listens on 0.0.0.0, not just localhost
# In your server.js:
app.listen(PORT, '0.0.0.0', () => {
  console.log(`Listening on port ${PORT}`);
});

Your Node.js App Is Live

You now have a production-ready Node.js application running on DeployBase with:

  • Node.js environment set up with one-click provisioning
  • SSH access for full control over your application
  • PM2 process manager keeping your app running reliably
  • PostgreSQL, MySQL, or Redis database connected
  • Free SSL certificate for HTTPS
  • Custom domain configured
  • Production security hardening applied
  • A clear deployment workflow for future updates

DeployBase makes Node.js hosting straightforward — one-click setup, SSH access on all plans, multi-database support, and free SSL mean you can focus on building your application instead of managing infrastructure.

Get started with DeployBase and deploy your Node.js application today.

Share this article

Muhammad Saad

Muhammad Saad

DeployBase Team

Ready to Get Started?

Join thousands of developers who trust DeployBase for their hosting needs.