Install NATS Server Message Broker on VPS
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:
- Publish/Subscribe: Send messages to multiple subscribers simultaneously without knowing their identities
- Request/Reply: Synchronous communication where requesters wait for responses from responders
- JetStream: Persistent streaming with replay capabilities and guaranteed delivery
- Clustering: Build fault-tolerant clusters for high availability
- Authentication & TLS: Secure connections with credentials and encryption
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
-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 .
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.