Install NATS Server Message Broker on VPS

Install NATS Server Message Broker on VPS

June 2026 · 9 min read

NATS Server is a lightweight, high-performance message broker designed for microservices architecture and real-time communication systems. It supports publish/subscribe messaging, request/reply patterns, and JetStream streaming with guaranteed delivery semantics. This guide walks you through installing and configuring NATS Server on your VPS, including clustering, authentication, and TLS security for production deployments.

What is NATS Server

NATS (Neural Autonomic Transport System) is an open-source message broker developed by Synadia Communications. It's engineered for high throughput, low latency, and minimal resource consumption, making it ideal for connecting microservices and distributed systems. Key features include:

Installation Methods

There are multiple ways to install NATS Server on your VPS. We'll cover the most common approaches for Linux systems.

1. Binary Installation from Release

# Check the latest release
curl -s https://api.github.com/repos/nats-io/nats-server/releases/latest | grep browser_download_url | grep linux-amd64 | head -1

# Download NATS Server
cd /tmp
wget https://github.com/nats-io/nats-server/releases/download/v2.10.0/nats-server-v2.10.0-linux-amd64.zip
unzip nats-server-v2.10.0-linux-amd64.zip

# Install to system path
sudo mv nats-server-v2.10.0-linux-amd64/nats-server /usr/local/bin/
sudo chmod +x /usr/local/bin/nats-server

# Verify installation
nats-server --version

2. Package Manager Installation (Ubuntu/Debian)

# Add Synadia repository
curl -1sLf 'https://open.synadia.com/install.sh' | sudo -E bash -

# Install NATS Server
sudo apt-get install nats-server

# Verify installation
nats-server --version

3. Docker Installation

# Pull Docker image
docker pull nats:latest

# Run NATS Server with JetStream enabled
docker run -d --name nats-server \
  -p 4222:4222 \
  -p 8222:8222 \
  nats:latest -js

# Check container logs
docker logs nats-server
Tip: The -js flag enables JetStream, which is required for persistent streaming functionality.

Basic Configuration

Create a configuration file to control NATS Server behavior. Save it at /etc/nats/nats.conf.

Minimal Configuration File

# /etc/nats/nats.conf
port: 4222

# Maximum message payload size
max_payload: 1MB

# Enable monitoring port
monitor_port: 8222

# Logging configuration
logfile: "/var/log/nats/nats.log"
loglevel: INFO

# JetStream persistent storage
jetstream {
  store_dir: "/var/lib/nats/jetstream"
  max_memory_store: 256MB
  max_file_store: 2GB
}

Create Required Directories

sudo mkdir -p /etc/nats
sudo mkdir -p /var/lib/nats/jetstream
sudo mkdir -p /var/log/nats
sudo chown -R nobody:nogroup /var/lib/nats
sudo chown -R nobody:nogroup /var/log/nats

Publish/Subscribe Messaging

This pattern allows publishers to broadcast messages to multiple subscribers without knowing who they are. It's ideal for event distribution and one-to-many communication patterns.

Publishing Messages

# Install NATS CLI tools
go install github.com/nats-io/natscli/cmd/nats@latest

# Publish to a subject
nats pub events.order "New order received"

# Publish multiple messages
nats pub events.order "Order #1001" &
nats pub events.order "Order #1002" &
nats pub events.order "Order #1003" &
wait

Subscribing to Messages

# Subscribe to a specific subject
nats sub "events.order"

# Subscribe with wildcards
nats sub "events.*"
nats sub ">"  # Subscribe to all messages

# Save messages to file
nats sub "events.>" -f /tmp/events.log

Request/Reply Pattern

Request/Reply enables synchronous communication where requesters wait for responses. Multiple responders can handle load distribution and failover automatically.

Setting up Responders

# Single responder
nats reply "service.requests" "Response from primary"

# Multiple responders for load balancing
for i in {1..3}; do
  nats reply "service.requests" "Response from instance $i" &
done
wait

Sending Requests

# Send request and wait for response (5 second timeout)
nats request "service.requests" "Process this data" --timeout 5s

# Send multiple concurrent requests
for i in {1..10}; do
  nats request "service.requests" "Request $i" &
done
wait

JetStream Streaming

JetStream provides persistent message storage with replay capabilities. Messages are retained even if subscribers are offline, and can be replayed from any point in time.

Creating Streams

# Create a stream named ORDERS
nats stream create ORDERS --subjects "orders.*"

# View stream information
nats stream info ORDERS

# Add data to the stream
nats pub orders.new "Order #1001: $50.00"
nats pub orders.new "Order #1002: $75.50"
nats pub orders.new "Order #1003: $120.00"

# List all streams
nats stream list

Creating Consumers

# Create a consumer for the ORDERS stream
nats consumer create ORDERS

# Consume the next message
nats consumer next ORDERS

# Subscribe to stream with consumer
nats sub orders.* --stream ORDERS

# View consumer info
nats consumer info ORDERS MYCONSUMER

Setting up Clustering

NATS clustering allows you to run multiple servers that replicate data and distribute load. This ensures high availability and fault tolerance.

Node 1 Configuration

# /etc/nats/nats-node1.conf
port: 4222
monitor_port: 8222

cluster {
  port: 6222
  name: "nats-cluster"
  routes: [
    nats-route://localhost:6223,
    nats-route://localhost:6224
  ]
}

jetstream {
  store_dir: "/var/lib/nats/jetstream-1"
  max_memory_store: 256MB
}

logfile: "/var/log/nats/nats-node1.log"

Node 2 & Node 3 Configuration

# /etc/nats/nats-node2.conf
port: 4223
monitor_port: 8223

cluster {
  port: 6223
  name: "nats-cluster"
  routes: [
    nats-route://localhost:6222,
    nats-route://localhost:6224
  ]
}

jetstream {
  store_dir: "/var/lib/nats/jetstream-2"
  max_memory_store: 256MB
}

logfile: "/var/log/nats/nats-node2.log"

Start the Cluster

# Start all three nodes
nats-server -c /etc/nats/nats-node1.conf &
nats-server -c /etc/nats/nats-node2.conf &
nats-server -c /etc/nats/nats-node3.conf &
wait

# Monitor cluster status
nats server list --all
nats server info server

Authentication and TLS Security

Secure your NATS deployment with credentials and encrypted connections to ensure only authorized applications can connect.

Create TLS Certificates

# Generate private key
openssl genrsa -out /etc/nats/nats-key.pem 2048

# Create self-signed certificate
openssl req -new -x509 -key /etc/nats/nats-key.pem \
  -out /etc/nats/nats-cert.pem -days 365 \
  -subj "/CN=nats.example.com"

# Set proper permissions
sudo chmod 600 /etc/nats/nats-key.pem
sudo chmod 644 /etc/nats/nats-cert.pem

Configuration with TLS and Authentication

# /etc/nats/nats-secure.conf
port: 4222
monitor_port: 8222

# TLS configuration
tls: {
  cert_file: "/etc/nats/nats-cert.pem"
  key_file: "/etc/nats/nats-key.pem"
}

# User authentication
authorization: {
  default_user: "user"
  default_permission: {
    publish: ">"
    subscribe: ">"
  }

  users: [
    {
      user: "admin"
      password: "$2y$11$yBe6RgFcHjgIvH.9sVR9I.e3M8r3CZT5dVyXhGVcXsxLPLqGcvfKa"
      permissions: {
        publish: ">"
        subscribe: ">"
      }
    },
    {
      user: "app1"
      password: "$2y$11$SZWNuTUE0GCplFVgbhH/xeDXqH.2kZxiMVjUZ5qFbVk9LzgKqL.T2"
      permissions: {
        publish: ["orders.*"]
        subscribe: ["orders.*", "events.*"]
      }
    }
  ]
}

jetstream {
  store_dir: "/var/lib/nats/jetstream"
  max_memory_store: 256MB
}

Verify NATS is Working

Perform these checks to ensure NATS Server is running correctly and responding to client connections.

Check Server Status

# Verify NATS process is running
ps aux | grep nats-server

# Check listening ports
netstat -tlnp | grep 4222

# Monitor logs in real-time
tail -f /var/log/nats/nats.log

Test Connectivity

# Test port with netcat
nc -zv localhost 4222

# Query monitoring endpoint
curl -s http://localhost:8222/varz | jq .

# Count active connections
curl -s http://localhost:8222/connz | jq '.connections | length'

# Check cluster info
curl -s http://localhost:8222/routez | jq .

Test Publish/Subscribe

# Simple pub/sub test
nats pub test.topic "Hello NATS"
nats sub "test.>"

# Stress test with multiple messages
nats pub bench.test "Test message" --count 1000

# Monitor server statistics
nats stats --raw

# Check JetStream status
curl -s http://localhost:8222/jsz | jq .
Tip: Use nats context list to view all configured servers and nats context select to switch between them.

Troubleshooting Common Issues

Here are common problems and their solutions when running NATS Server.

Error: Address already in use

This occurs when port 4222 is already in use by another process. Identify and stop the conflicting service or use a different port.

# Find process using the port
lsof -i :4222
sudo netstat -tlnp | grep 4222

# Terminate the process (example: PID 12345)
sudo kill -9 12345

# Or change the port in configuration
port: 4223

Error: Permission denied on directories

NATS cannot access configured directories due to insufficient permissions. Verify and fix ownership and permissions.

# Check current permissions
ls -la /var/lib/nats/
ls -la /var/log/nats/

# Fix directory ownership and permissions
sudo chown -R nobody:nogroup /var/lib/nats
sudo chown -R nobody:nogroup /var/log/nats
sudo chmod 755 /var/lib/nats
sudo chmod 755 /var/log/nats

Error: Client could not connect

When clients cannot establish connections to NATS, verify firewall rules and network accessibility. Check that ports are properly exposed.

# Open firewall ports
sudo ufw allow 4222
sudo ufw allow 8222
sudo ufw allow 6222  # For clustering

# Verify NATS configuration syntax
nats-server -c /etc/nats/nats.conf --verify-config

# Check recent error logs
tail -50 /var/log/nats/nats.log | grep -i error

Error: JetStream not enabled

When attempting to use JetStream features without enabling it first, add JetStream configuration and restart the server.

# Add to NATS configuration
jetstream {
  store_dir: "/var/lib/nats/jetstream"
  max_memory_store: 256MB
  max_file_store: 2GB
}

# Restart NATS to apply changes
sudo systemctl restart nats-server

# Verify JetStream is enabled
curl -s http://localhost:8222/varz | jq '.jetstream'

Frequently Asked Questions

How does NATS compare to RabbitMQ?

NATS is lighter weight, faster, and uses less memory, making it ideal for microservices requiring high throughput. RabbitMQ offers more features and better durability guarantees, making it suitable for traditional message queue scenarios. Choose NATS for speed and simplicity; choose RabbitMQ for complex routing and advanced features.

Can I connect from remote machines?

Yes, but you must open port 4222 for client connections. Use nats context save --url nats://server-ip:4222 to add remote servers to your NATS CLI, then use nats context select to switch between them. For security, always use TLS and authentication on exposed instances.

How long can I retain messages in JetStream?

You can configure retention policies based on message count, time, or storage size. For example, nats stream create ORDERS --retention limits --max-msgs 10000 --max-age 7d keeps only the last 10,000 messages or 7 days, whichever comes first. Storage size can be limited with --max-bytes 1GB.