Vendure on VPS: TypeScript Headless Commerce Framework for Developers

31.03.2026
12:21

Vendure is not a CMS with a storefront and admin panel. It's a headless commerce framework built on TypeScript and Node.js that exposes a GraphQL API for Shop and Admin operations, while the frontend — Next.js, React, Vue, a mobile app, anything — is built separately on top of it. This approach is called API-first or headless: the backend handles only data and business logic, and the frontend is fully independent.

Current version: Vendure 3.5.2. Built on NestJS, powered by Apollo Server for GraphQL, admin dashboard built with React and Tailwind. Supported databases: PostgreSQL (recommended), MySQL, MariaDB, SQLite. License: GPLv3 for the open-source core.

This guide covers who Vendure is for, how to install it on THE.Hosting VPS in any of 50+ locations — from Germany (Frankfurt) to Japan (Tokyo), from Netherlands (Meppel) to the US (New Jersey) — and how to run it in production with PostgreSQL, Redis, and PM2.

Who Vendure Is For

Vendure is a tool for developers. If you're used to WordPress or PrestaShop where everything can be configured through a UI without writing code — Vendure is not for you. This requires writing TypeScript, understanding NestJS, GraphQL, and knowing how to deploy Node.js applications.

Vendure is the right choice when: you need an API-first e-commerce backend with full freedom in frontend selection; you're building a headless store on top of Next.js or React Native; you need a customizable platform for B2B, a marketplace, or a non-standard commerce project; you want enterprise-quality architecture with TypeScript, NestJS patterns, and a well-designed plugin system; independence from SaaS providers with predetermined roadmaps matters.

Vendure is not the right choice if you need a ready-to-use store that launches without development. For that, look at LiteCart, osCommerce, PrestaShop, or WooCommerce.

Vendure Architecture

Understanding the architecture before installation saves confusion at every step.

Vendure Server — the main process. Handles HTTP requests, serves the GraphQL API, manages transactions. Listens on port 3000 by default.

Vendure Worker — a separate process for background tasks. Processes the job queue via BullMQ: email sending, search indexing, image processing, data import. Critical in production — without the worker, background tasks don't execute.

PostgreSQL — the primary database. Stores all store data.

Redis — used by BullMQ as the message broker between server and worker. Required in production.

GraphQL API — two endpoints: /shop-api for the storefront (shoppers) and /admin-api for admin operations.

Dashboard — React-based admin interface accessible at /dashboard. Operates on top of the Admin GraphQL API.

Storefront — the frontend for shoppers. Vendure doesn't provide one out of the box. An official Next.js Storefront Starter is available and connects to the Shop API.

System Requirements

  • Node.js v20, v22, or v24 (officially tested versions; v18+ works but isn't officially supported)
  • PostgreSQL 12+ (recommended), MySQL 8+, or MariaDB 10.3+
  • Redis 6+ (for the BullMQ job queue in production)
  • Minimum 4 GB RAM for a VPS running Vendure + PostgreSQL + Redis
  • 10+ GB disk space

TypeScript is a mandatory part of the ecosystem. Vendure scaffolds a TypeScript project and its configuration is a TypeScript object.

Preparing the VPS

Connect:

ssh root@your-IP-address

Update the system:

apt update && apt upgrade -y
apt install -y curl wget git build-essential

Create a working user:

adduser vendure
usermod -aG sudo vendure
su - vendure

Firewall (from root or via sudo):

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 3000/tcp   # temporary, for initial verification
ufw enable

Timezone:

timedatectl set-timezone America/New_York

Installing Node.js

Install Node.js 22 LTS via nvm — this enables version management without conflicts:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install 22
nvm use 22
nvm alias default 22
node --version    # v22.x.x
npm --version

Installing PostgreSQL

sudo apt install postgresql postgresql-contrib -y
sudo systemctl start postgresql
sudo systemctl enable postgresql

Create the database and user:

sudo -u postgres psql
CREATE DATABASE vendure;
CREATE USER vendure_user WITH PASSWORD 'strong_password';
GRANT ALL PRIVILEGES ON DATABASE vendure TO vendure_user;
\c vendure
GRANT ALL ON SCHEMA public TO vendure_user;
\q

Verify the connection:

psql -h localhost -U vendure_user -d vendure

Installing Redis

sudo apt install redis-server -y
sudo systemctl start redis-server
sudo systemctl enable redis-server

Verify:

redis-cli ping
# PONG

Creating the Vendure Project

Use the official @vendure/create tool:

cd ~
npx @vendure/create my-shop

The tool prompts for configuration. Select:

  • How should we proceed? → Manual Configuration (for production with PostgreSQL and Redis)
  • Which database are you using? → Postgres
  • Database host address → localhost
  • Port → 5432
  • Database name → vendure
  • Database username → vendure_user
  • Database password → your_password
  • Populate with some sample data? → Yes (for initial testing)
  • Include the Next.js storefront? → No (add later if needed)

Navigate into the project directory:

cd my-shop

Production Configuration

Open the server config file — typically apps/server/src/vendure-config.ts or src/vendure-config.ts depending on the version:

nano apps/server/src/vendure-config.ts

Configure the Redis connection for BullMQ:

import { VendureConfig } from '@vendure/core';
import { BullMQJobQueuePlugin } from '@vendure/job-queue-plugin/package/bullmq';

export const config: VendureConfig = {
  apiOptions: {
    port: 3000,
    adminApiPath: 'admin-api',
    shopApiPath: 'shop-api',
  },
  dbConnectionOptions: {
    type: 'postgres',
    host: process.env.DB_HOST || 'localhost',
    port: 5432,
    username: process.env.DB_USERNAME || 'vendure_user',
    password: process.env.DB_PASSWORD || 'your_password',
    database: process.env.DB_NAME || 'vendure',
    synchronize: false,  // always false in production!
    migrations: ['src/migrations/*.ts'],
  },
  plugins: [
    BullMQJobQueuePlugin.init({
      connection: {
        host: process.env.REDIS_HOST || 'localhost',
        port: 6379,
      },
    }),
    // ... other plugins
  ],
};

Create a .env file in the project root for sensitive credentials:

nano .env
DB_HOST=localhost
DB_USERNAME=vendure_user
DB_PASSWORD=your_strong_password
DB_NAME=vendure
REDIS_HOST=localhost
COOKIE_SECRET=long_random_string_for_signing_sessions
SUPERADMIN_USERNAME=superadmin
SUPERADMIN_PASSWORD=your_admin_password

Building and First Run

Install dependencies and build the project:

cd my-shop
npm ci
npx vite build   # builds the admin dashboard
npm run build    # compiles TypeScript

Run it once to verify everything works:

npm run start:server

Vendure applies database migrations, seeds initial data, and starts the server. The logs should show:

Vendure server (pid: XXXXX) now listening on port 3000

Open http://your-IP:3000/dashboard in a browser — the admin dashboard. Log in with the credentials from .env (SUPERADMIN_USERNAME / SUPERADMIN_PASSWORD).

Stop the process (Ctrl+C) — now set up the production runner.

PM2 for Production

PM2 is a Node.js process manager. It starts, restarts on crash, and survives server reboots:

npm install -g pm2

Create a PM2 config in the project root:

nano ecosystem.config.js
module.exports = {
  apps: [
    {
      name: 'vendure-server',
      script: 'apps/server/dist/index.js',
      instances: 1,
      env: {
        NODE_ENV: 'production',
        PORT: 3000,
      },
      env_file: '.env',
    },
    {
      name: 'vendure-worker',
      script: 'apps/server/dist/index-worker.js',
      instances: 1,
      env: {
        NODE_ENV: 'production',
      },
      env_file: '.env',
    },
  ],
};

Start both processes:

pm2 start ecosystem.config.js
pm2 save
pm2 startup   # copy and run the output command for autostart on reboot

Check status:

pm2 status
pm2 logs vendure-server
pm2 logs vendure-worker

Both processes should show online status.

Nginx as Reverse Proxy

Vendure listens on port 3000; Nginx accepts HTTPS traffic on 443 and proxies requests through:

sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/vendure

Content:

server {
    listen 80;
    server_name yourstore.com www.yourstore.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name yourstore.com www.yourstore.com;

    ssl_certificate /etc/letsencrypt/live/yourstore.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourstore.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        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;
        proxy_cache_bypass $http_upgrade;
    }
}
sudo ln -s /etc/nginx/sites-available/vendure /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

SSL certificate:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourstore.com -d www.yourstore.com

After obtaining the certificate, close direct access to port 3000:

ufw delete allow 3000/tcp

Choosing a VPS at THE.Hosting

Vendure needs more resources than typical PHP platforms. Node.js + PostgreSQL + Redis + Vendure Worker — that's several processes running in memory simultaneously.

Production minimum: Standard VPS with 4 vCPU / 4 GB RAM / 80 GB NVMe. Real-world tests show a 4 GB RAM server handles approximately 240 orders per minute with p95 response time under 500 ms.

For growth: 4 vCPU / 8 GB RAM lets you scale comfortably — increase PM2 instances, add pgBouncer for PostgreSQL connection pooling.

Location by audience:

European market: Germany (Frankfurt) — financial hub and GDPR compliance; Netherlands (Meppel) — best connectivity for pan-European headless projects; UK (London) — for UK-oriented storefronts.

American audience: USA (New Jersey, Secaucus) — East Coast with low latency for Next.js storefronts; Canada (Toronto) — Canadian market.

Asian market: Japan (Tokyo) — lowest latency for East Asia; Hong Kong — gateway to China and Southeast Asia.

CIS and Eastern Europe: Moldova (Chișinău) — Dedicated servers available; Finland (Helsinki) — minimal latency for Russia.

Vendure benefits particularly from NVMe drives on THE.Hosting VPS — PostgreSQL is disk-intensive with complex catalog queries.

Common Issues

PostgreSQL connection error. Confirm the user has rights on the public schema — a requirement from PostgreSQL 15+. Run in psql: \c vendureGRANT ALL ON SCHEMA public TO vendure_user;.

Vendure Worker can't connect to Redis. Verify Redis is running (redis-cli ping → PONG) and the correct host is set in the BullMQJobQueuePlugin config. Check logs: pm2 logs vendure-worker.

Dashboard doesn't load after deploy. Confirm you ran npx vite build to build the dashboard. Without this step the UI won't work in production.

TypeScript compilation errors during build. Vendure is pinned to a specific TypeScript version — don't upgrade TypeScript independently without checking compatibility in the current Vendure release changelog.

PM2 can't find the entry point. Verify the correct path to compiled files in ecosystem.config.js — it depends on whether @vendure/create scaffolded a monorepo or a single project. Check with ls -la dist/ or ls -la apps/server/dist/.

Ready to launch your headless store on Vendure?

THE.Hosting VPS with NVMe drives, root access, and 50+ locations is built for Node.js platforms. Configure PostgreSQL, Redis, and PM2 exactly to your requirements.

Order VPS for Vendure

FAQ:

Is a separate frontend required? Yes, it's mandatory. Vendure is a headless framework: it provides a GraphQL API but doesn't include a ready storefront for shoppers. An official Next.js Storefront Starter is available and connects to the Shop API. It can be included when creating the project via @vendure/create or added later.

Is Vendure free? The open-source core (Vendure Core) is under GPLv3 — free. Vendure Ltd also offers a commercial cloud platform with additional enterprise features and support. The self-hosted version on a VPS is completely free.

Why is a separate Worker process needed? Vendure Server synchronously handles API requests. Heavy tasks — email sending, search indexing, image processing, large catalog imports — are placed in a queue and processed asynchronously by the Worker. Without a running Worker, tasks accumulate in Redis without ever being processed.

Which database should I choose? PostgreSQL is the officially recommended and most thoroughly tested database for Vendure. MySQL and MariaDB are supported; SQLite is for local development only. Use PostgreSQL in production.

Can Vendure be used without TypeScript? Technically Node.js runs compiled jаvascript, but developing plugins and customizations without TypeScript means giving up the platform's primary advantage. Vendure is designed for TypeScript developers.

THE.Hosting Useful Links:

Vendure Resources:

Other articles

31.03.2026
3
Knowledge base / All about domains
.MOBI Domain Zone
31.03.2026
3
Knowledge base / All about domains
.HOSTING Domain Zone