How to Deploy KeystoneJS on Ubuntu with Nginx and PM2

Post Date: January 7, 2020
Last Updated: November 10, 2026

Introduction

KeystoneJS is an open-source Node.js framework for building database-driven applications and content management systems. It provides a configurable Admin UI, GraphQL API, authentication capabilities, and flexible data management.

Deploying a KeystoneJS application on an Ubuntu server requires configuring the Node.js runtime, installing application dependencies, setting up a database, and configuring a web server to handle incoming requests.

In this guide, we will explain how to deploy KeystoneJS on Ubuntu 24.04 LTS using Nginx and PM2. We will also cover domain configuration, application process management, and basic deployment verification.

Prerequisites

Before starting the deployment, make sure you have:

  • An Ubuntu 24.04 LTS server.
  • Root or sudo access to the server.
  • A domain name pointing to your server’s public IP address.
  • A KeystoneJS 6 application or a new project.
  • SSH access to the server.
  • A database supported by your KeystoneJS configuration, such as PostgreSQL, MySQL, or SQLite.
  • Basic knowledge of Linux commands and Node.js.

Note: This guide uses Node.js 24 LTS as the example runtime. Check your application’s dependencies and package.json before selecting a Node.js version. Node.js 26 is also available as an Active LTS release.

Implementation

Step 1: Install and Configure Nginx

Nginx will act as a reverse proxy, forwarding incoming HTTP requests to the KeystoneJS application running on the local application port.

1.1 Update Ubuntu packages

Connect to your server through SSH and update the package repository.

sudo apt update
sudo apt upgrade -y

1.2 Install Nginx

Install the Nginx web server.

sudo apt install nginx -y

Check the Nginx service status.

sudo systemctl status nginx

If the service is not running, start and enable it.

sudo systemctl start nginx
sudo systemctl enable nginx

1.3 Verify Nginx installation

Open your browser and access:

http://SERVER_IP_ADDRESS

You should see the default Nginx welcome page.

1.4 Configure your domain directory

Create a directory for your domain.

sudo mkdir -p /var/www/domainname.com/html

Assign ownership to your deployment user.

sudo chown -R $USER:$USER /var/www/domainname.com/html

Set the appropriate directory permissions.

sudo chmod -R 755 /var/www/domainname.com

Create a sample HTML page to verify the domain configuration.

nano /var/www/domainname.com/html/index.html

Add the following content:

<html>
<head>
    <title>KeystoneJS Deployment</title>
</head>
<body>
    <h1>Nginx is configured successfully!</h1>
</body>
</html>

Save and close the file.

1.5 Configure the Nginx server block

Create a configuration file for your domain.

sudo nano /etc/nginx/sites-available/domainname.com

Add the following configuration:

server {
    listen 80;
    listen [::]:80;

    server_name domainname.com www.domainname.com;

    root /var/www/domainname.com/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Enable the configuration by creating a symbolic link.

sudo ln -s /etc/nginx/sites-available/domainname.com /etc/nginx/sites-enabled/

Test the Nginx configuration.

sudo nginx -t

If the configuration test succeeds, reload Nginx.

sudo systemctl reload nginx

Your domain should now display the sample HTML page.

Step 2: Install Node.js and npm

KeystoneJS runs on Node.js. We will install Node.js 24 using the NodeSource repository.

First, install the required packages.

sudo apt install curl ca-certificates -y

Add the Node.js 24 repository.

curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -

Install Node.js.

sudo apt install nodejs -y

Verify the installed versions.

node -v
npm -v

Make sure the installed Node.js version is compatible with your KeystoneJS application’s dependencies.

Step 3: Create or Prepare the KeystoneJS Application

You can either create a new KeystoneJS application or deploy an existing project.

Option 1: Create a new KeystoneJS project

For a new project, run:

npm create keystone-app@latest

Follow the prompts to create your application.

Navigate to the project directory.

cd my-app

Install the dependencies.

npm install

Start the application in development mode for initial testing.

npm run dev

By default, the development server runs at:

http://localhost:3000

Option 2: Deploy an existing KeystoneJS application

If you already have a KeystoneJS project hosted in a Git repository, install Git.

sudo apt install git -y

Clone your project.

git clone YOUR_GIT_REPOSITORY_URL

Navigate to the application directory.

cd YOUR_PROJECT_DIRECTORY

Install the application dependencies.

npm ci

Use npm ci when your repository contains a valid package-lock.json. Otherwise, follow the package manager and installation instructions specified by your project.

Step 4: Configure the Database

KeystoneJS 6 uses Prisma for database access.

It supports the following database providers:

  • PostgreSQL
  • MySQL
  • SQLite

The database provider is configured in the KeystoneJS project configuration.

For production deployments, use an appropriately secured database and configure its connection details through environment variables.

For example, an environment file may contain:

DATABASE_URL="YOUR_DATABASE_CONNECTION_STRING"

The actual variable name and connection format must match your application’s Prisma and KeystoneJS configuration.

Create or update the environment file in your project directory.

nano .env

Add the required application environment variables and database connection details.

Restrict access to the environment file.

chmod 600 .env

Note: Do not commit .env files, database credentials, or other application secrets to your Git repository.

Before proceeding, confirm that the database is reachable from the application server and that the application is configured for the correct database provider.

Step 5: Build the KeystoneJS Application

Before starting KeystoneJS in production mode, generate the production build.

Navigate to the application directory.

cd YOUR_PROJECT_DIRECTORY

Run the production build.

npx keystone build

If your project uses Prisma migrations, deploy the committed production migrations.

npx prisma migrate deploy

Run database migrations against the intended production database only. Do not run production migrations from staging or preview deployments.

For production deployments, KeystoneJS recommends building the application and starting it using its production commands.

Step 6: Install and Configure PM2

PM2 is a process manager for Node.js applications. It helps keep the application running in the background and allows administrators to monitor and manage application processes.

Install PM2 globally.

sudo npm install -g pm2

Navigate to your KeystoneJS project directory.

cd YOUR_PROJECT_DIRECTORY

Start the application using PM2.

pm2 start npm --name keystone -- start

Check the application status.

pm2 status

View application logs.

pm2 logs keystone

To monitor the application:

pm2 monit

Configure PM2 to start automatically

Save the current PM2 process list.

pm2 save

Generate the startup command.

pm2 startup

PM2 will display a command that needs to be executed with elevated privileges. Copy and execute the command shown in your terminal.

This configures PM2 to restore the saved application processes after a server restart.

Step 7: Configure Nginx as a Reverse Proxy

Now that KeystoneJS is running on the local application port, configure Nginx to forward requests to it.

Open the Nginx configuration file.

sudo nano /etc/nginx/sites-available/domainname.com

Replace the earlier sample HTML configuration with the following:

server {
    listen 80;
    listen [::]:80;

    server_name domainname.com www.domainname.com;

    location / {
        proxy_pass http://127.0.0.1:3000;

        proxy_http_version 1.1;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Save the configuration and test it.

sudo nginx -t

If the syntax is valid, reload Nginx.

sudo systemctl reload nginx

Nginx will now forward incoming requests to the KeystoneJS application running on port 3000.

Step 8: Configure Firewall Rules

If UFW is enabled, allow the required web traffic.

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'

Check the firewall status.

sudo ufw status

For production, expose only the required public services. Keep the KeystoneJS application port restricted to localhost or the private network rather than opening port 3000 publicly.

Step 9: Verify the KeystoneJS Deployment

Open your browser and access your domain:

http://domainname.com

Your KeystoneJS application should respond through Nginx.

You can also test the application locally from the server.

curl -I http://127.0.0.1:3000

Check the PM2 process status.

pm2 status

Review the application logs if the application does not respond.

pm2 logs keystone

For production environments, configure HTTPS using a valid SSL/TLS certificate and redirect HTTP traffic to HTTPS.

Troubleshooting Common KeystoneJS Deployment Issues

1. KeystoneJS application is not starting

Check the PM2 logs.

pm2 logs keystone

Verify that dependencies are installed and the required environment variables are available.

2. Nginx returns a 502 Bad Gateway error

A 502 error commonly occurs when Nginx cannot communicate with the application.

Check the application process.

pm2 status

Verify that KeystoneJS is listening on the expected port.

sudo ss -lntp | grep 3000

Confirm that the Nginx proxy_pass destination matches the application’s actual listening address and port.

3. Database connection errors

Verify the database connection string, database availability, network access, and database credentials.

Check that Prisma migrations have been applied successfully.

4. Application does not start after a server reboot

Check whether PM2 has been configured for startup.

pm2 startup
pm2 save

Also verify the PM2 systemd service and its associated user configuration.

Conclusion

Deploying KeystoneJS on Ubuntu involves configuring the Node.js runtime, preparing the application and database, building the production application, and managing its process through PM2.

By configuring Nginx as a reverse proxy, you can serve your KeystoneJS application through a domain name without exposing the application port directly to the public internet.

Following these steps provides a foundation for running a KeystoneJS application in a production environment. Remember to maintain supported software versions, secure application credentials, configure HTTPS, and monitor application and database health.

Frequently Asked Questions

1. What is KeystoneJS?

KeystoneJS is an open-source Node.js framework used to build database-driven applications, content management systems, and GraphQL APIs.

2. Can I deploy KeystoneJS on Ubuntu 24.04?

Yes. You can deploy KeystoneJS on Ubuntu 24.04 by installing a compatible Node.js runtime, configuring a supported database, and setting up a production web server.

3. Why is PM2 used with KeystoneJS?

PM2 manages Node.js application processes. It provides process monitoring, log management, background execution, and automatic restart capabilities.

4. Why use Nginx with KeystoneJS?

Nginx acts as a reverse proxy, forwarding incoming HTTP or HTTPS requests to the KeystoneJS application. It also helps manage domain routing and SSL/TLS configuration.

5. Does KeystoneJS support MongoDB?

The current KeystoneJS 6 database configuration supports PostgreSQL, MySQL, and SQLite through Prisma. MongoDB is not a supported database provider in the standard KeystoneJS 6 configuration.

References

Need Assistance?

Need help deploying KeystoneJS, configuring Nginx, or managing Node.js applications on Ubuntu servers?

The Pheonix Solutions technical team can assist with application deployment, server configuration, cloud infrastructure, and DevOps services.

For assistance, contact us.

Leave a Comment

Scroll to Top