MinusNow Documentation

โฌ‡๏ธ Download Center

Download source code, pre-built artifacts, installer scripts, and monitoring agents. All scripts are served directly from this server.

๐Ÿ”

Verify downloads: After downloading archives, verify their integrity with the SHA256 checksums file.

Windows: Get-FileHash .\minusnow-itsm-source.zip -Algorithm SHA256

Linux: sha256sum -c SHA256SUMS.txt

1. Overview

MinusNow is a full-stack ITSM (IT Service Management) platform built with:

ComponentTechnology
RuntimeNode.js 20 LTS
BackendExpress.js 4.x + TypeScript 5.6
FrontendReact 19 + Vite 7 + Tailwind CSS 4
DatabasePostgreSQL 15+ (via Drizzle ORM)
AuthPassport.js (Local + optional LDAP)
SessionsIn-memory (memorystore)

This guide covers single-node deployment where the application and database run on the same machine. Ideal for:

โ„น๏ธ

Default port: 5000 โ€” serves both the API and the web UI.


2. Prerequisites

Minimum Hardware

ResourceMinimumRecommended
CPU2 cores4 cores
RAM4 GB8 GB
Disk10 GB free20 GB free
NetworkLocalhostLAN/Internet

Required Software

SoftwareVersionPurpose
Node.js20 LTSApplication runtime
npm10+Package manager (ships with Node.js)
PostgreSQL15+Database
Git2.40+Source code management

Optional Software

SoftwarePurpose
LDAP/AD ServerActive Directory authentication
SMTP ServerEmail notifications

3. Windows Installation

๐Ÿ–ฅ๏ธ

Tested on: Windows 10/11 (x64)

1

Install Node.js 20 LTS

  1. Download the Windows Installer (.msi) from: https://nodejs.org/en/download
  2. Choose Node.js 20 LTS (the recommended version).
  3. Run the installer. Accept the defaults, ensuring "Add to PATH" is checked.
  4. Verify installation โ€” open a new PowerShell or Command Prompt:
PowerShellnode --version
# Expected: v20.x.x

npm --version
# Expected: 10.x.x
2

Install PostgreSQL

  1. Download the Windows installer from: https://www.postgresql.org/download/windows/
  2. Run the installer (EDB installer recommended). During setup:
    • Set a password for the postgres superuser โ€” remember this password.
    • Keep the default port 5432.
    • Accept other defaults (locale, data directory).
  3. The installer includes pgAdmin โ€” a GUI tool for managing the database.
  4. Verify installation โ€” open a new PowerShell:
PowerShellpsql --version
# Expected: psql (PostgreSQL) 15.x or higher
โš ๏ธ

If psql is not found, add PostgreSQL's bin directory to your PATH. Default location: C:\Program Files\PostgreSQL\15\bin

PowerShell# Add to PATH for current session
$env:PATH += ";C:\Program Files\PostgreSQL\15\bin"
3

Create the Database

Open PowerShell and run:

SQL# Connect as the postgres superuser
psql -U postgres

# At the psql prompt, create the database and a dedicated user:
CREATE DATABASE minusnow;
CREATE USER minusnow_user WITH ENCRYPTED PASSWORD 'YourStrongPassword123!';
GRANT ALL PRIVILEGES ON DATABASE minusnow TO minusnow_user;
ALTER DATABASE minusnow OWNER TO minusnow_user;

# Exit psql
\q

Verify the connection:

PowerShellpsql -U minusnow_user -d minusnow -h localhost
# Enter your password when prompted. If you see the psql prompt, it works.
\q
4

Install Git (if not installed)

  1. Download from: https://git-scm.com/download/win
  2. Run the installer with default settings.
  3. Verify:
PowerShellgit --version
# Expected: git version 2.x.x
5

Clone the Repository

PowerShell# Navigate to your preferred project directory
cd E:\Projects

# Clone the repository
git clone <your-repo-url> MinusNow

# Enter the project directory
cd MinusNow
โ„น๏ธ

If you already have the source code, skip cloning and navigate to the project root.

6

Install Dependencies

PowerShellnpm install

Expected output ends with: added 800+ packages in 30s

โš ๏ธ

If you encounter errors:

  • Run npm cache clean --force and retry.
  • Ensure you have a stable internet connection.
  • On corporate networks, configure npm proxy: npm config set proxy http://proxy:port
7

Configure Environment Variables

โ„น๏ธ

What is a .env file?

A .env file is a simple text file that stores configuration settings (like database passwords, ports, etc.) that your application reads at startup. It keeps sensitive information out of your source code. The file lives in the project root folder (e.g., E:\Projects\MinusNow\.env).

Step 7a: Create the file in your project folder:

PowerShell# Make sure you are inside the project folder
cd E:\Projects\MinusNow

# Create the .env file
New-Item -Path .env -ItemType File -Force

Step 7b: Open the file in Notepad (or any text editor):

PowerShellnotepad .env

Step 7c: Paste the following into the file, then edit the values marked with โ†:

.env# โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
# โ”‚  REQUIRED โ€” App will NOT start without these     โ”‚
# โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

# Your PostgreSQL connection string
# Format: postgresql://USERNAME:PASSWORD@HOST:PORT/DATABASE_NAME
#
# โ† Replace the username, password, and database name with what
#    you created in Step 3 when setting up PostgreSQL.
#
#    Example breakdown:
#    postgresql://minusnow_user:YourStrongPassword123!@localhost:5432/minusnow
#                โ”œโ”€โ”€ username โ”€โ”€โ”คโ”œโ”€โ”€ your password โ”€โ”€โ”€โ”€โ”คโ”œโ”€ host โ”€โ”คโ”œportโ”คโ”œโ”€ db โ”€โ”ค
#
DATABASE_URL=postgresql://minusnow_user:YourStrongPassword123!@localhost:5432/minusnow

# A secret key used to encrypt user sessions (login cookies).
# โ† Replace with any random string of 32+ characters.
#    (See the tip below to auto-generate one.)
#
SESSION_SECRET=change-me-to-a-random-string-at-least-32-characters-long


# โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
# โ”‚  OPTIONAL โ€” Safe to leave as-is for local testingโ”‚
# โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

# Which port the app listens on (default: 5000)
PORT=5000

# Set to "production" when deploying for real users
NODE_ENV=development

# Your company name (shown in the UI header)
# APP_ORG_NAME=YourCompany

# Admin email for notifications
# ADMIN_EMAIL=admin@yourcompany.com

# Active Directory / LDAP (only if your org uses AD login)
# AD_URL=ldap://your-ad-server:389
# AD_DOMAIN=YOURDOMAIN
# AD_EMAIL_DOMAIN=yourcompany.com

# App URL (used in email links โ€” only needed if sending emails)
# APP_BASE_URL=http://localhost:5000
# APP_URL=http://localhost:5000

Step 7d: Save the file (Ctrl + S in Notepad) and close it.

๐Ÿ’ก

Quick way to generate a random SESSION_SECRET:

Run this in PowerShell โ€” it prints a random string you can copy-paste:

[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 }) -as [byte[]])

Copy the output and paste it as your SESSION_SECRET value.

๐Ÿ“‹ Quick Reference โ€” What each variable does
VariableRequired?What it doesExample Value
DATABASE_URLโœ… YesTells the app how to connect to PostgreSQLpostgresql://user:pass@localhost:5432/minusnow
SESSION_SECRETโœ… YesEncrypts login session cookiesaB3x9Kz... (32+ chars)
PORTNoPort number for the web server5000 (default)
NODE_ENVNoSwitches between dev/production modedevelopment
APP_ORG_NAMENoCompany name shown in the UIMyCompany
AD_URLNoLDAP server for Active Directory loginldap://ad-server:389
โš ๏ธ

Common mistakes to avoid:

  • Spaces around = โ€” Write PORT=5000, NOT PORT = 5000
  • Quotes โ€” Do NOT wrap values in quotes. Write SESSION_SECRET=abc123, NOT SESSION_SECRET="abc123"
  • Wrong password โ€” The password in DATABASE_URL must match what you set in Step 3
  • Wrong database name โ€” Must match the database you created (e.g., minusnow)
โœ…

How to verify your .env is correct:

# This should print your DATABASE_URL (confirms the file is being read)
Get-Content .env | Select-String "DATABASE_URL"

You should see your connection string printed. If it's blank, the file is empty or in the wrong location.

8

Initialize the Database Schema

PowerShellnpm run db:push

Expected output: [โœ“] Changes applied

โš ๏ธ

If this fails:

  • Verify DATABASE_URL in your .env is correct.
  • Ensure PostgreSQL is running: Get-Service postgresql*
  • Check that the database minusnow exists.
9

Build the Application

PowerShellnpm run build

This compiles the TypeScript backend and builds the React frontend. Build artifacts are placed in dist/:

  • dist/index.cjs โ€” compiled server
  • dist/public/ โ€” compiled frontend assets
10

Start the Application

For testing/development:

PowerShellnpm run dev

For production:

PowerShellnpm run start
11

Access the Application

Open your browser and navigate to:

http://localhost:5000

You should see the MinusNow login page.

12

Windows Firewall (Optional)

If you need to access the application from other devices on your network:

PowerShell (Admin)# Run as Administrator
New-NetFirewallRule -DisplayName "MinusNow ITSM" -Direction Inbound -Port 5000 -Protocol TCP -Action Allow

4. Linux Installation

๐Ÿง

Tested on: Ubuntu 22.04/24.04 LTS, Debian 12, RHEL 9, Rocky Linux 9

1

Update System Packages

Ubuntu/Debian:

Bashsudo apt update && sudo apt upgrade -y

RHEL/Rocky Linux:

Bashsudo dnf update -y
2

Install Node.js 20 LTS

Ubuntu/Debian (via NodeSource):

Bash# Install Node.js 20.x repository
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -

# Install Node.js
sudo apt install -y nodejs

# Verify
node --version   # Expected: v20.x.x
npm --version    # Expected: 10.x.x

RHEL/Rocky Linux (via NodeSource):

Bash# Install Node.js 20.x repository
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -

# Install Node.js
sudo dnf install -y nodejs

# Verify
node --version
npm --version
3

Install PostgreSQL

Ubuntu/Debian:

Bash# Install PostgreSQL
sudo apt install -y postgresql postgresql-contrib

# Start and enable the service
sudo systemctl start postgresql
sudo systemctl enable postgresql

# Verify
sudo systemctl status postgresql
psql --version

RHEL/Rocky Linux:

Bash# Install PostgreSQL
sudo dnf install -y postgresql-server postgresql-contrib

# Initialize the database cluster
sudo postgresql-setup --initdb

# Start and enable the service
sudo systemctl start postgresql
sudo systemctl enable postgresql

# Verify
sudo systemctl status postgresql
4

Create the Database

SQL# Switch to the postgres system user
sudo -u postgres psql

# At the psql prompt:
CREATE DATABASE minusnow;
CREATE USER minusnow_user WITH ENCRYPTED PASSWORD 'YourStrongPassword123!';
GRANT ALL PRIVILEGES ON DATABASE minusnow TO minusnow_user;
ALTER DATABASE minusnow OWNER TO minusnow_user;
\q
โš ๏ธ

If you get authentication errors, edit pg_hba.conf:

sudo -u postgres psql -c "SHOW hba_file;"
sudo nano /etc/postgresql/15/main/pg_hba.conf

Change peer to md5 for local connections, then: sudo systemctl restart postgresql

Verify the connection:

Bashpsql -U minusnow_user -d minusnow -h localhost
# Enter password when prompted
\q
5

Install Git (if not installed)

Bash# Ubuntu/Debian
sudo apt install -y git

# RHEL/Rocky Linux
sudo dnf install -y git

# Verify
git --version
6

Clone the Repository

Bash# Navigate to installation directory
cd /opt

# Clone the repository
sudo git clone <your-repo-url> minusnow

# Set ownership (replace 'youruser' with your username)
sudo chown -R youruser:youruser /opt/minusnow

# Enter the project directory
cd /opt/minusnow
7

Install Dependencies

Bashnpm install
8

Configure Environment Variables

โ„น๏ธ

What is a .env file?

A .env file is a simple text file that stores configuration settings (like database passwords, ports, etc.) that your application reads at startup. It keeps sensitive information out of your source code. The file lives in the project root folder (e.g., /opt/minusnow/.env).

Step 8a: Create and open the file:

Bash# Make sure you are inside the project folder
cd /opt/minusnow

# Create and open the file in nano editor
nano .env

Step 8b: Paste the following, then edit the values marked with โ†:

.env# โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
# โ”‚  REQUIRED โ€” App will NOT start without these     โ”‚
# โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

# Your PostgreSQL connection string
# Format: postgresql://USERNAME:PASSWORD@HOST:PORT/DATABASE_NAME
#
# โ† Replace the username, password, and database name with what
#    you created in Step 4 when setting up PostgreSQL.
#
#    Example breakdown:
#    postgresql://minusnow_user:YourStrongPassword123!@localhost:5432/minusnow
#                โ”œโ”€โ”€ username โ”€โ”€โ”คโ”œโ”€โ”€ your password โ”€โ”€โ”€โ”€โ”คโ”œโ”€ host โ”€โ”คโ”œportโ”คโ”œโ”€ db โ”€โ”ค
#
DATABASE_URL=postgresql://minusnow_user:YourStrongPassword123!@localhost:5432/minusnow

# A secret key used to encrypt user sessions (login cookies).
# โ† Replace with any random string of 32+ characters.
#    (See the tip below to auto-generate one.)
#
SESSION_SECRET=change-me-to-a-random-string-at-least-32-characters-long


# โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
# โ”‚  OPTIONAL โ€” Safe to leave as-is for local testingโ”‚
# โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

# Which port the app listens on (default: 5000)
PORT=5000

# Set to "production" when deploying for real users
NODE_ENV=development

# Your company name (shown in the UI header)
# APP_ORG_NAME=YourCompany

# Admin email for notifications
# ADMIN_EMAIL=admin@yourcompany.com

# Active Directory / LDAP (only if your org uses AD login)
# AD_URL=ldap://your-ad-server:389
# AD_DOMAIN=YOURDOMAIN
# AD_EMAIL_DOMAIN=yourcompany.com

# App URL (used in email links โ€” only needed if sending emails)
# APP_BASE_URL=http://localhost:5000
# APP_URL=http://localhost:5000

Step 8c: Save the file โ€” in nano press Ctrl + O, then Enter, then Ctrl + X to exit.

Step 8d: Secure the file so only your user can read it:

Bashchmod 600 .env
๐Ÿ’ก

Quick way to generate a random SESSION_SECRET:

openssl rand -base64 32

Copy the output and paste it as your SESSION_SECRET value.

๐Ÿ“‹ Quick Reference โ€” What each variable does
VariableRequired?What it doesExample Value
DATABASE_URLโœ… YesTells the app how to connect to PostgreSQLpostgresql://user:pass@localhost:5432/minusnow
SESSION_SECRETโœ… YesEncrypts login session cookiesaB3x9Kz... (32+ chars)
PORTNoPort number for the web server5000 (default)
NODE_ENVNoSwitches between dev/production modedevelopment
APP_ORG_NAMENoCompany name shown in the UIMyCompany
AD_URLNoLDAP server for Active Directory loginldap://ad-server:389
โš ๏ธ

Common mistakes to avoid:

  • Spaces around = โ€” Write PORT=5000, NOT PORT = 5000
  • Quotes โ€” Do NOT wrap values in quotes. Write SESSION_SECRET=abc123, NOT SESSION_SECRET="abc123"
  • Wrong password โ€” The password in DATABASE_URL must match what you set in Step 4
  • Wrong database name โ€” Must match the database you created (e.g., minusnow)
โœ…

How to verify your .env is correct:

grep DATABASE_URL .env

You should see your connection string printed. If it's blank, the file is empty or in the wrong location.

9

Initialize the Database Schema

Bashnpm run db:push
10

Build the Application

Bashnpm run build
11

Start the Application

For testing/development:

Bashnpm run dev

For production:

Bashnpm run start
12

Access the Application

http://localhost:5000

Or from another machine on the same network: http://<server-ip>:5000

13

Set Up as a systemd Service (Production)

Bashsudo nano /etc/systemd/system/minusnow.service

Add the following content:

systemd[Unit]
Description=MinusNow ITSM Platform
After=network.target postgresql.service
Wants=postgresql.service

[Service]
Type=simple
User=youruser
Group=youruser
WorkingDirectory=/opt/minusnow
EnvironmentFile=/opt/minusnow/.env
Environment=NODE_ENV=production
ExecStart=/usr/bin/node /opt/minusnow/dist/index.cjs
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=minusnow

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/minusnow/data /opt/minusnow/audit-logs /opt/minusnow/artifacts /opt/minusnow/support-tickets /opt/minusnow/ticket-responses

[Install]
WantedBy=multi-user.target

Enable and start the service:

Bash# Reload systemd configuration
sudo systemctl daemon-reload

# Enable the service (starts on boot)
sudo systemctl enable minusnow

# Start the service
sudo systemctl start minusnow

# Check status
sudo systemctl status minusnow

# View logs
sudo journalctl -u minusnow -f
14

Linux Firewall (Optional)

UFW (Ubuntu/Debian):

Bashsudo ufw allow 5000/tcp
sudo ufw reload

firewalld (RHEL/Rocky Linux):

Bashsudo firewall-cmd --permanent --add-port=5000/tcp
sudo firewall-cmd --reload

5. Environment Variables Reference

Required Variables

VariableDescriptionExample
DATABASE_URLPostgreSQL connection stringpostgresql://user:password@localhost:5432/minusnow
SESSION_SECRETSession encryption key (32+ chars, required in production)a8f2c9e1b4d7f6a3e0c5b8d1a4f7e2c9

Optional Variables

VariableDefaultDescription
PORT5000HTTP server port
NODE_ENVdevelopmentdevelopment or production
APP_ORG_NAMEMinusNowOrganization name displayed in the UI
ADMIN_EMAILadministrator@localhostDefault admin email address
AD_URL(empty โ€” LDAP disabled)LDAP/AD server URL
AD_DOMAIN(empty)Active Directory domain name
AD_EMAIL_DOMAINlocalEmail domain for AD users
APP_BASE_URL(auto-detected)Base URL for email links
APP_URLhttp://localhost:5000Application URL for email templates
ACCOUNT_IDACC-000001Organization account identifier
CUSTOMER_IDCUST-000001Organization customer identifier
ORG_COUNTRY(empty)Organization country
ORG_ADDRESS(empty)Organization address

6. Post-Installation Verification

After starting the application, verify each component:

6.1 Application Health

Open your browser to http://localhost:5000. You should see the MinusNow landing page or login screen.

6.2 Database Connectivity

The application logs will show successful startup:

XX:XX:XX AM [express] serving on port 5000

6.3 API Verification

Windows (PowerShell):

PowerShellInvoke-WebRequest -Uri http://localhost:5000/api/health -UseBasicParsing | Select-Object StatusCode, Content

Linux:

Bashcurl -s http://localhost:5000/api/health

6.4 Quick Checklist

CheckHow to VerifyExpected Result
Application startsConsole shows serving on port 5000No errors in console
Web UI loadsOpen http://localhost:5000 in browserLogin or landing page
Database connectionApplication starts without DB errorsClean startup log
Static assets servedPage loads with styles and imagesStyled page, no 404s
Session worksLogin with credentialsRedirected to dashboard

7. Running in Development Mode

Development mode enables:

Terminal# Windows or Linux
npm run dev
โ„น๏ธ

In development mode, the Vite dev server handles frontend assets with HMR. The Express server and Vite run in the same process on port 5000.


8. Running in Production Mode

8.1 Build

Terminalnpm run build

8.2 Set Environment

Ensure your .env has:

.envNODE_ENV=production
SESSION_SECRET=your-strong-random-session-secret-at-least-32-chars

8.3 Start

Terminalnpm run start

This runs cross-env NODE_ENV=production node dist/index.cjs which:

8.4 Reverse Proxy (Recommended for Production)

For production, place a reverse proxy in front of MinusNow for HTTPS:

Nginxserver {
    listen 80;
    server_name minusnow.yourcompany.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name minusnow.yourcompany.com;

    ssl_certificate     /etc/ssl/certs/minusnow.crt;
    ssl_certificate_key /etc/ssl/private/minusnow.key;

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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;
    }
}

9. Automated Installer Scripts

MinusNow ships with ready-made installer scripts in documentation/downloads/ that automate the installation process.

๐Ÿ–ฅ๏ธ Windows Automated Installer

Script: documentation/downloads/install-windows.ps1

Basic usage:

PowerShellPowerShell -ExecutionPolicy Bypass -File .\documentation\downloads\install-windows.ps1

With firewall & service:

PowerShellPowerShell -ExecutionPolicy Bypass -File .\documentation\downloads\install-windows.ps1 `
  -InstallDir "C:\MinusNow" `
  -OpenFirewall `
  -ServiceName "MinusNow"
ParameterDefaultDescription
-InstallDirCurrent directoryTarget installation directory
-OpenFirewallfalseOpens Windows Firewall for port 5000
-ServiceName(none)Register as a Windows service using NSSM
โ„น๏ธ

The -ServiceName option requires NSSM (Non-Sucking Service Manager).

What the script does:

  1. Checks that Node.js and npm are available
  2. Creates the installation directory (if different from current)
  3. Copies project files (excluding node_modules, dist, .git)
  4. Creates .env from .env.example (if .env doesn't exist)
  5. Runs npm install and npm run build
  6. Optionally opens Windows Firewall for TCP port 5000
  7. Optionally registers and starts a Windows service via NSSM

๐Ÿง Linux Automated Installer

Script: documentation/downloads/install-linux.sh

Basic usage:

Bashsudo bash documentation/downloads/install-linux.sh

With systemd service:

Bashsudo bash documentation/downloads/install-linux.sh /opt/MinusNow minusnow
PositionDefaultDescription
1Current directoryTarget installation directory
2(none)systemd service name (creates .service)

What the script does:

  1. Checks that Node.js and npm are available
  2. Creates the installation directory
  3. Copies project files via rsync (excluding node_modules, dist, .git)
  4. Creates .env from .env.example (if .env doesn't exist)
  5. Runs npm install and npm run build
  6. Optionally creates, enables, and starts a systemd service

10. Agent Deployment

MinusNow includes lightweight monitoring agents that run on managed endpoints. Agents register with the MinusNow server and send periodic heartbeats to report asset status.

๐Ÿ–ฅ๏ธ Windows Agent

Script: documentation/downloads/agent-install-windows.ps1

The Windows agent installs as a Scheduled Task that runs every 1 minute.

Prerequisites:

  • PowerShell 5.1+ (built into Windows 10/11)
  • Run as Administrator
  • Network access to the MinusNow server

Installation:

PowerShell (Admin)PowerShell -ExecutionPolicy Bypass -File .\documentation\downloads\agent-install-windows.ps1 `
  -Server https://minusnow.yourcompany.com `
  -Org YOUR_ORG_ID
ParameterRequiredDefaultDescription
-ServerYesโ€”MinusNow server URL
-OrgYesโ€”Organization ID
-AssetIdNo$env:COMPUTERNAMEUnique asset identifier
-TaskNameNoMinusNowAgentScheduled Task name

What gets installed:

  • Config: C:\ProgramData\MinusNow\agent.json
  • Script: C:\ProgramData\MinusNow\agent.ps1
  • Scheduled Task: MinusNowAgent (every 1 minute)

Verify:

PowerShellGet-ScheduledTask -TaskName "MinusNowAgent"
Get-Content "C:\ProgramData\MinusNow\agent.json"

Uninstall:

PowerShell (Admin)Unregister-ScheduledTask -TaskName "MinusNowAgent" -Confirm:$false
Remove-Item -Recurse -Force "C:\ProgramData\MinusNow"

๐Ÿง Linux Agent

Script: documentation/downloads/agent-install-linux.sh

The Linux agent installs as a systemd timer that fires every 60 seconds.

Prerequisites:

  • curl installed
  • Run as root (sudo)
  • systemd (present on most modern Linux distros)
  • Network access to the MinusNow server

Installation:

Bashsudo bash documentation/downloads/agent-install-linux.sh \
  --server https://minusnow.yourcompany.com \
  --org YOUR_ORG_ID
FlagRequiredDefaultDescription
--serverYesโ€”MinusNow server URL
--orgYesโ€”Organization ID
--asset-idNo$(hostname -f)Unique asset identifier

What gets installed:

  • Config: /etc/minusnow/agent.conf
  • Script: /usr/local/bin/minusnow-agent.sh
  • Service: minusnow-agent.service
  • Timer: minusnow-agent.timer (every 60 seconds)

Verify:

Bashsystemctl status minusnow-agent.timer
cat /etc/minusnow/agent.conf
sudo journalctl -u minusnow-agent -f

Uninstall:

Bashsudo systemctl disable --now minusnow-agent.timer
sudo rm /etc/systemd/system/minusnow-agent.service
sudo rm /etc/systemd/system/minusnow-agent.timer
sudo systemctl daemon-reload
sudo rm -rf /etc/minusnow
sudo rm /usr/local/bin/minusnow-agent.sh

11. Packaging and Distribution

MinusNow provides packaging scripts to create distributable archives for deployment on machines without internet access or source code.

๐Ÿ–ฅ๏ธ Packaging on Windows

Script: documentation/downloads/package-windows.ps1

PowerShell# Quick method:
npm run package:win

# Or with options:
PowerShell -ExecutionPolicy Bypass -File .\documentation\downloads\package-windows.ps1 `
  -OutputDir .\artifacts -Build
ParameterDefaultDescription
-OutputDir./artifactsDirectory for output archives
-BuildfalseRun npm install and npm run build first
-SourceOnlyfalseOnly create the source archive

๐Ÿง Packaging on Linux

Script: documentation/downloads/package-linux.sh

Bash# Quick method:
npm run package:linux

# Or with options:
bash documentation/downloads/package-linux.sh --build --output-dir ./artifacts
FlagDefaultDescription
--output-dir./artifactsDirectory for output archives
--buildoffRun npm install and npm run build first
--source-onlyoffOnly create the source archive

Output Files

FileContents
minusnow-source.zipFull source code (excluding node_modules, dist, .git)
minusnow-artifact.zipBuilt dist/ + production node_modules + package.json
๐Ÿ”’

Security: The packaging scripts automatically exclude founder-credentials.json from all archives.

11.3 Deploying from an Artifact Package

To deploy on a target machine using the artifact archive (no build required):

Windows

PowerShell# 1. Extract the artifact
Expand-Archive -Path minusnow-artifact.zip -DestinationPath C:\MinusNow

# 2. Create .env file
cd C:\MinusNow
@"
DATABASE_URL=postgresql://user:password@localhost:5432/minusnow
SESSION_SECRET=your-secret-here
NODE_ENV=production
PORT=5000
"@ | Out-File -Encoding utf8 .env

# 3. Push database schema
npx drizzle-kit push

# 4. Start the application
node dist/index.cjs

Linux

Bash# 1. Extract the artifact
mkdir -p /opt/minusnow
tar -xzf minusnow-artifact.tar.gz -C /opt/minusnow

# 2. Create .env file
cat > /opt/minusnow/.env << 'EOF'
DATABASE_URL=postgresql://user:password@localhost:5432/minusnow
SESSION_SECRET=your-secret-here
NODE_ENV=production
PORT=5000
EOF
chmod 600 /opt/minusnow/.env

# 3. Push database schema
cd /opt/minusnow && npx drizzle-kit push

# 4. Start the application
node dist/index.cjs

12. Backup and Restore

12.1 Application Backup

MinusNow includes backup scripts to snapshot the workspace.

๐Ÿ–ฅ๏ธ Windows Backup

PowerShell# Basic backup (excludes node_modules and dist)
PowerShell -ExecutionPolicy Bypass -File .\documentation\downloads\backup-windows.ps1

# Backup to a custom directory
PowerShell -ExecutionPolicy Bypass -File .\documentation\downloads\backup-windows.ps1 `
  -OutputDir "D:\Backups\MinusNow"

# Include node_modules and dist
PowerShell -ExecutionPolicy Bypass -File .\documentation\downloads\backup-windows.ps1 `
  -IncludeDependencies

Output: backups/minusnow-YYYYMMDD-HHMMSS.zip

๐Ÿง Linux Backup

Bash# Basic backup
bash documentation/downloads/backup-linux.sh

# Backup to a custom directory
bash documentation/downloads/backup-linux.sh --output-dir /var/backups/minusnow

# Include node_modules and dist
bash documentation/downloads/backup-linux.sh --include-deps

Output: backups/minusnow-YYYYMMDD-HHMMSS.tar.gz

12.2 Database Backup

Always back up the PostgreSQL database separately:

Create a dumppg_dump -U minusnow_user -h localhost -d minusnow -F c -f minusnow-db-backup.dump
Restore from a dump# Drop and recreate the database first
psql -U postgres -c "DROP DATABASE IF EXISTS minusnow;"
psql -U postgres -c "CREATE DATABASE minusnow OWNER minusnow_user;"

# Restore
pg_restore -U minusnow_user -h localhost -d minusnow minusnow-db-backup.dump

12.3 Scheduled Backups (Recommended)

Windows (Task Scheduler)

PowerShell$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
  -Argument "-ExecutionPolicy Bypass -File C:\MinusNow\documentation\downloads\backup-windows.ps1 -OutputDir D:\Backups\MinusNow"
$trigger = New-ScheduledTaskTrigger -Daily -At 2:00AM
Register-ScheduledTask -TaskName "MinusNow-Backup" -Action $action -Trigger $trigger

Linux (cron)

Bash# Add to crontab (runs daily at 2 AM)
crontab -e
# Add this line:
0 2 * * * cd /opt/minusnow && bash documentation/downloads/backup-linux.sh --output-dir /var/backups/minusnow

13. Enrollment Token Activation (Final Step)

After deploying MinusNow and completing all configuration steps, the final step is activating your organization with an enrollment token. Until activated, the application runs in read-only mode — all dashboards, incidents, alerts, and monitoring data are visible, but creating, editing, or deleting records is disabled.

13.1 How It Works

1

Access the Portal

Open your browser to http://server:5000 and sign in with your credentials.

2

Navigate to Settings → Enrollment

The Enrollment tab is the first tab in Settings, highlighted with an amber indicator when not yet activated.

3

Enter Your Enrollment Token

Paste the enrollment token provided by the MinusNow technical team in the format MNOW-[TYPE]-[YEAR]-[CODE]-[CODE].

4

Click Activate

The system validates the token and upgrades your organization from read-only to full access immediately.

13.2 Obtaining a Token

Enrollment tokens are provided exclusively by the MinusNow founder/technical team during customer onboarding. Contact:

ChannelContact
Emailsupport@minusnow.com
Webwww.minusnow.com/support
Phone+1 (555) 123-4567

13.3 License Tiers

Token PrefixLicenseDurationFeatures
MNOW-TRL-Trial30 daysAll features, limited users
MNOW-STD-Standard1 yearCore ITSM, monitoring, alerting
MNOW-PRO-Professional1 yearAll modules + AI chatbot + advanced reporting
MNOW-ENT-Enterprise1 yearUnlimited users, SSO, audit logs, priority support

13.4 Access Comparison

CapabilityWithout Token (Read-Only)With Token (Activated)
View dashboards & data
Browse incidents, alerts, changes
Create / edit / delete records
Manage teams and users
Execute commands & runbooks
Upload files & export data
โ„น๏ธ

Note: Founder accounts (MinusNow technical team) always have full access regardless of enrollment status. Tokens are single-use per organization. To upgrade your license tier, enter a new enrollment token.


14. Troubleshooting

โ„น๏ธ

These are real issues encountered during installation testing on a Windows laptop in February 2026. Each one has a verified fix.

14.1 drizzle-kit: "unknown command 'push'"

Symptomnpm run db:push โ†’ error: unknown command 'push'
Root CauseAn old global drizzle-kit (v0.18.x) is installed and takes precedence over the local v0.31.8. In v0.18.x, the command was push:pg, not push.

How to diagnose

PowerShell# Check which version is running
npx drizzle-kit --version
# If it shows v0.18.x instead of v0.31.8 โ† this is the problem

# Check for a global installation
npm list -g drizzle-kit

Fix (Windows)

PowerShell# 1. Remove the old global version
npm uninstall -g drizzle-kit

# 2. Delete lock file & node_modules to force clean install
Remove-Item -Force package-lock.json
Remove-Item -Recurse -Force node_modules

# 3. Clear npm cache
npm cache clean --force

# 4. Reinstall everything fresh
npm install

# 5. Verify correct version
npx drizzle-kit --version
# Should show: drizzle-kit: v0.31.8

# 6. Now push the schema
npm run db:push

Fix (Linux)

Bashsudo npm uninstall -g drizzle-kit
rm -f package-lock.json
rm -rf node_modules
npm cache clean --force
npm install
npx drizzle-kit --version    # Should show v0.31.8
npm run db:push
โš ๏ธ

If it still shows the old version, force-install the correct one: npm install drizzle-kit@0.31.8 --save-dev

14.2 PostgreSQL: "permission denied for schema public"

Symptomnpm run db:push โ†’ error: permission denied for schema public
Root CausePostgreSQL 15+ changed default permissions โ€” the public schema no longer grants CREATE to all users. Your minusnow_user needs explicit permission.

Fix

SQL (run as postgres superuser)# Connect as superuser
psql -U postgres -h localhost

# Grant permissions (paste all 5 lines)
GRANT ALL ON SCHEMA public TO minusnow_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO minusnow_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO minusnow_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO minusnow_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO minusnow_user;
\q

Or as a one-liner:

PowerShell / Bashpsql -U postgres -h localhost -d minusnow -c "GRANT ALL ON SCHEMA public TO minusnow_user; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO minusnow_user; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO minusnow_user; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO minusnow_user; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO minusnow_user;"

Then retry: npm run db:push

14.3 PostgreSQL: psql not found / must navigate to bin folder

Symptompsql is not recognized. You must cd to C:\Program Files\PostgreSQL\18\bin every time.
Root CausePostgreSQL's bin directory was not added to the system PATH during installation.

Fix (Windows โ€” run PowerShell as Administrator)

PowerShell (Admin)# Add PostgreSQL to system PATH permanently
# โ† Change the version number (18) to match your PostgreSQL version
[Environment]::SetEnvironmentVariable(
    "Path",
    $env:Path + ";C:\Program Files\PostgreSQL\18\bin",
    [EnvironmentVariableTarget]::Machine
)

Important: Close and reopen PowerShell after running this. Then verify:

PowerShell (new window)psql --version
# Should show: psql (PostgreSQL) 18.x
๐Ÿ’ก

How to find your PostgreSQL version: Check C:\Program Files\PostgreSQL\ โ€” the folder name (15, 16, 17, 18) is your version number.

14.4 DATABASE_URL, ensure the database is provisioned

SymptomRunning npm run db:push or npm run dev prints: DATABASE_URL, ensure the database is provisioned
Root CauseThe .env file is missing, empty, or DATABASE_URL is not set.

How to diagnose

PowerShell# Check if .env exists and has DATABASE_URL
Get-Content .env | Select-String "DATABASE_URL"
# Should print your connection string. If blank โ†’ problem found.

Fix

  • Ensure .env exists in the project root (same folder as package.json)
  • Ensure it contains DATABASE_URL=postgresql://... with no spaces around =
  • Ensure PostgreSQL is running: Get-Service postgresql*
  • Test the connection directly: psql "postgresql://minusnow_user:YourPassword@localhost:5432/minusnow"

14.5 SESSION_SECRET must be set in production

Cause: Running in production mode (NODE_ENV=production) without SESSION_SECRET.

Fix: Add SESSION_SECRET to your .env file. Generate one:

Windows

PowerShell[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 }) -as [byte[]])

Linux

Bashopenssl rand -base64 32

14.6 Port 5000 already in use

Fix option 1: Change the port in .env: PORT=5001

Fix option 2: Find and stop the conflicting process:

Windows

PowerShell# Find what's using port 5000
Get-NetTCPConnection -LocalPort 5000 | Select-Object OwningProcess

# Kill it
Stop-Process -Id <PID> -Force

Linux

Bashsudo lsof -i :5000
kill <PID>

14.7 npm run db:push โ€” connection refused

Cause: PostgreSQL is not running or not accepting connections on port 5432.

Windows

PowerShellGet-Service postgresql*
# If stopped:
Start-Service postgresql-x64-18

Linux

Bashsudo systemctl status postgresql
# If stopped:
sudo systemctl start postgresql

14.8 npm install fails with permission errors (Linux)

Cause: Running as root or incorrect file ownership.

Bashsudo chown -R $(whoami):$(whoami) /opt/minusnow
npm install --unsafe-perm

14.9 Frontend shows a blank page

Cause: Build was not run, or dist/public/ is missing.

Terminalnpm run build
npm run start

14.10 LDAP authentication not working

Cause: LDAP environment variables not configured.

.envAD_URL=ldap://your-ad-server:389
AD_DOMAIN=YOURDOMAIN
AD_EMAIL_DOMAIN=yourcompany.com

14.11 Checking Logs

Development mode: Logs appear directly in the terminal where you ran npm run dev.

Linux systemd service:

Bash# Follow live logs
sudo journalctl -u minusnow -f

# View last 100 lines
sudo journalctl -u minusnow -n 100

Windows: Logs appear in the PowerShell terminal where you ran the start command.

14.12 Reset Everything

Terminal# Stop the application (Ctrl+C or stop the service)

# Drop and recreate the database
psql -U postgres -c "DROP DATABASE IF EXISTS minusnow;"
psql -U postgres -c "CREATE DATABASE minusnow OWNER minusnow_user;"

# Grant schema permissions (PostgreSQL 15+)
psql -U postgres -d minusnow -c "GRANT ALL ON SCHEMA public TO minusnow_user;"

# Rebuild
npm run build

# Re-push schema
npm run db:push

# Start
npm run start

15. Uninstallation

๐Ÿ–ฅ๏ธ Windows

  1. Stop the application (Ctrl+C in the terminal).
  2. Remove the firewall rule (if created):
    PowerShellRemove-NetFirewallRule -DisplayName "MinusNow ITSM"
  3. Drop the database:
    PowerShellpsql -U postgres -c "DROP DATABASE IF EXISTS minusnow;"
    psql -U postgres -c "DROP USER IF EXISTS minusnow_user;"
  4. Delete the project directory.
  5. Optionally uninstall Node.js and PostgreSQL via Settings > Apps.

๐Ÿง Linux

  1. Stop and disable the service:
    Bashsudo systemctl stop minusnow
    sudo systemctl disable minusnow
    sudo rm /etc/systemd/system/minusnow.service
    sudo systemctl daemon-reload
  2. Drop the database:
    Bashsudo -u postgres psql -c "DROP DATABASE IF EXISTS minusnow;"
    sudo -u postgres psql -c "DROP USER IF EXISTS minusnow_user;"
  3. Remove the firewall rule:
    Bash# UFW
    sudo ufw delete allow 5000/tcp
    
    # firewalld
    sudo firewall-cmd --permanent --remove-port=5000/tcp
    sudo firewall-cmd --reload
  4. Delete the project directory:
    Bashsudo rm -rf /opt/minusnow

Appendix A: Quick Start (TL;DR)

๐Ÿ–ฅ๏ธ Windows โ€” 5-Minute Setup

PowerShell# 1. Prerequisites: Install Node.js 20 LTS and PostgreSQL 15+

# 2. Create database
psql -U postgres -c "CREATE DATABASE minusnow;"
psql -U postgres -c "CREATE USER minusnow_user WITH ENCRYPTED PASSWORD 'YourPassword123!';"
psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE minusnow TO minusnow_user;"
psql -U postgres -c "ALTER DATABASE minusnow OWNER TO minusnow_user;"

# 3. Navigate to project
cd E:\Projects\HIkePost\MinusNow

# 4. Install dependencies
npm install

# 5. Create .env file
@"
DATABASE_URL=postgresql://minusnow_user:YourPassword123!@localhost:5432/minusnow
SESSION_SECRET=change-this-to-a-strong-random-string-32chars
PORT=5000
NODE_ENV=development
"@ | Out-File -Encoding utf8 .env

# 6. Push database schema
npm run db:push

# 7. Start development server
npm run dev

# 8. Open http://localhost:5000

๐Ÿง Linux โ€” 5-Minute Setup

Bash# 1. Install prerequisites (Ubuntu/Debian)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs postgresql postgresql-contrib git
sudo systemctl start postgresql && sudo systemctl enable postgresql

# 2. Create database
sudo -u postgres psql -c "CREATE DATABASE minusnow;"
sudo -u postgres psql -c "CREATE USER minusnow_user WITH ENCRYPTED PASSWORD 'YourPassword123!';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE minusnow TO minusnow_user;"
sudo -u postgres psql -c "ALTER DATABASE minusnow OWNER TO minusnow_user;"

# 3. Navigate to project
cd /opt/minusnow

# 4. Install dependencies
npm install

# 5. Create .env file
cat > .env << 'EOF'
DATABASE_URL=postgresql://minusnow_user:YourPassword123!@localhost:5432/minusnow
SESSION_SECRET=change-this-to-a-strong-random-string-32chars
PORT=5000
NODE_ENV=development
EOF
chmod 600 .env

# 6. Push database schema
npm run db:push

# 7. Start development server
npm run dev

# 8. Open http://localhost:5000

Appendix B: npm Scripts Reference

CommandDescription
npm run devStart development server with HMR
npm run buildBuild for production (output to dist/)
npm run startStart production server from dist/
npm run checkRun TypeScript type checking
npm run db:pushPush database schema to PostgreSQL
npm run package:winPackage application for Windows distribution
npm run package:linuxPackage application for Linux distribution
npm run security:scanRun security vulnerability scan
npm run security:auditRun npm audit for dependency vulnerabilities

Appendix C: Download Scripts Reference

All scripts are located in documentation/downloads/:

ScriptPlatformPurpose
install-windows.ps1WindowsAutomated app installer (build + service)
install-linux.shLinuxAutomated app installer (build + systemd)
agent-install-windows.ps1WindowsMonitoring agent (Scheduled Task heartbeat)
agent-install-linux.shLinuxMonitoring agent (systemd timer heartbeat)
package-windows.ps1WindowsCreate source + artifact ZIP archives
package-linux.shLinuxCreate source + artifact TAR.GZ archives
backup-windows.ps1WindowsTimestamped workspace backup (ZIP)
backup-linux.shLinuxTimestamped workspace backup (TAR.GZ)