Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Install NATS Server 2.15.1 on Ubuntu, validate a local publish/subscribe flow, then move to a restricted configuration, authentication, TLS, persistent JetStream storage, and a hardened systemd service. The commands below cover both a quick test and a boot-starting production baseline.

Plan the Ubuntu deployment

NATS Server is a lightweight messaging server. Core NATS provides fast, ephemeral publish/subscribe delivery; JetStream adds persistence, replay and retention. Decide which mode you need before creating directories or a service account.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Core NATS only: messages are delivered to currently connected subscribers and are not written to disk.
  • JetStream: streams and consumers can retain and replay messages, so the server needs a deliberate filesystem location and suitable storage capacity.
  • Client port: the default listener is TCP 4222.
  • Monitoring: the HTTP endpoint is commonly exposed on 8222, but it should remain on a controlled administrative network.
  • Privileges: use a dedicated unprivileged nats account for the systemd service rather than running the daemon as root.

Have an Ubuntu host with sudo, outbound access to download the binary or package, and a hostname plan for TLS. If clients will connect remotely, decide which interface should listen and which firewall rules should permit 4222. Do not expose an unauthenticated listener to an untrusted network.

Choose an installation method and version

The current official release identified for this guide is NATS Server v2.15.1, released October 9, 2026. The release page publishes Debian packages for amd64, arm64, arm6, arm7 and 386, so choose the package that matches the Ubuntu machine’s architecture. A package install integrates with Debian’s package database; the official Linux installer is convenient when you want the upstream binary in a controlled path.

Method Best fit Version behavior Operational note
Versioned Debian asset Hosts managed through Ubuntu/Debian package workflows Select a specific 2.15.1 architecture package Download the matching .deb, verify its release checksum, then install it with dpkg or your package workflow.
Official Linux installer Quick setup or a binary installed under /usr/local/bin The documented command tracks latest Pin a release in production instead of silently tracking latest; record the selected version and verify a versioned artifact’s checksum.

The installer endpoint documented by NATS is https://binaries.nats.dev/nats-io/nats-server/v2@latest. It downloads a file named nats-server into the current directory.

Install NATS Server

Install with the official Linux command

  1. Change to a temporary working directory and run the documented installer:
curl -sf https://binaries.nats.dev/nats-io/nats-server/v2@latest | sh
  1. Install the binary in a system path:
sudo install -m 0755 nats-server /usr/local/bin/nats-server
  1. Confirm what is installed. This command is the official verification check:
nats-server --version

For a production rollout, replace the floating installer approach with a version-pinned release asset, record the exact release and architecture, and compare the downloaded file with the checksum published for that release. Keeping the binary in /usr/local/bin also means the systemd unit must use that exact path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install a Debian package

From the NATS release page, download the .deb for the host architecture (amd64, arm64, arm6, arm7 or 386). Verify the release checksum before installation, then install the downloaded file with your normal Ubuntu package workflow. Afterward, run nats-server --version and note whether the package placed the executable somewhere other than /usr/local/bin; that path matters when you write ExecStart later.

Run a safe smoke test

Before adding systemd, prove that the executable can start and that clients can exchange a message. Start a foreground server on a host where only local users can reach it:

nats-server

The default client listener is 4222. In another terminal, the NATS getting-started flow uses one subscriber and one publisher:

nats sub hello &
nats pub hello "Hello NATS!"

The subscriber should print the published message. Stop the foreground process with Ctrl+C after the check.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a development-only monitoring test, start the server with:

nats-server -m 8222

Port 8222 exposes HTTP monitoring and is an administrative surface, not a replacement for client authentication. Keep it bound to a controlled network or omit it entirely on a public interface.

To try JetStream temporarily without a configuration file, use:

nats-server -js

This is suitable for a disposable test. Persistent data requires an explicit store_dir, ownership and a storage policy, covered below.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create and validate the server configuration

Create /etc/nats-server.conf with ownership and permissions that prevent ordinary users from reading credentials or changing listener settings. A minimal local configuration with persistent JetStream storage is:

listen: "127.0.0.1:4222"

# Uncomment for controlled local monitoring only.
# http: 8222

jetstream {
  store_dir: "/var/lib/nats/jetstream"
}

The configuration syntax accepts comments, either = or : assignments, arrays and maps. Validate every change before restarting:

sudo nats-server -t -c /etc/nats-server.conf

A successful validation does not prove that a certificate, directory or port is usable at runtime; it confirms that NATS can parse the configuration. Run the test as part of each rollout so a syntax error cannot take down the service unexpectedly.

Enable authentication before remote access

A bare NATS server has security disabled by default. For a small centrally managed installation, put users in the authorization block:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
authorization {
  users: [
    { user: app, password: "replace-with-a-long-secret" }
  ]
}

Replace the example value with a long, unique secret, protect the configuration file, and start the server with:

sudo nats-server -c /etc/nats-server.conf

Centralized authentication means the server holds the complete user list in its own configuration. It is straightforward for a small team, but every user change requires a controlled configuration update and rollout.

Authentication model Use when Strengths Trade-offs
Users in authorization One small, centrally administered deployment Simple file-based setup and easy initial testing One server configuration contains the full user list; rotation and delegated administration become harder as teams grow.
NATS credentials/JWT model Multiple accounts, delegated administration or larger deployments Account isolation and a model designed for distributed credential management More components and operational procedure than a single local user block.

Authentication answers who may connect. It does not encrypt traffic; use TLS when credentials or messages cross an untrusted network.

Encrypt client connections with TLS

Add certificate paths to the server configuration when clients must connect over TLS:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
listen: "0.0.0.0:4222"
tls {
  cert_file: "/etc/nats/certs/server-cert.pem"
  key_file: "/etc/nats/certs/server-key.pem"
  ca_file: "/etc/nats/certs/ca.pem"
  timeout: 2
}
  • Store the private key where only the service account and approved administrators can read it.
  • Make sure the certificate’s Subject Alternative Name contains the hostname clients actually use. A certificate for a different name will fail hostname verification even when the server is reachable.
  • Keep the CA file that clients trust available through your normal secret or configuration distribution process.
  • Run sudo nats-server -t -c /etc/nats-server.conf before launch.

When TLS is required, a plaintext client is refused during the handshake. TLS protects transport; it does not replace NATS authorization, and it does not encrypt JetStream files stored on disk. Treat transport security, client identity and at-rest protection as separate controls.

Configure persistent JetStream storage

JetStream is built into nats-server. The -js flag enables it for a temporary process, while a jetstream block with store_dir makes storage location part of the persistent configuration. Create the directory with ownership matching the service account:

sudo install -d -o nats -g nats -m 0750 /var/lib/nats/jetstream

Choose fast local storage that fits the stream retention and replication requirements. The service should be able to write inside this directory and nowhere else. Keep backups and capacity alerts outside NATS itself; a full filesystem can prevent new messages from being persisted.

Characteristic Core NATS JetStream
Delivery Ephemeral delivery to connected subscribers Stored messages can be replayed by consumers
Disk requirement No message store required Requires a writable store_dir
Retention No server-side retention Retention and stream policy determine how long data remains
Operational concern Listener availability and client reconnection Storage capacity, filesystem permissions and recovery planning

After the service is running, use the NATS CLI to create or inspect a stream and confirm that files appear only below the configured store_dir.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Run NATS as a hardened systemd service

Create the service account and directories

Create a system account named nats with no interactive login, install the configuration in /etc/nats-server.conf, and ensure the JetStream path is owned by that account. If TLS is enabled, apply similarly restrictive ownership to /etc/nats/certs, especially the private key.

sudo useradd --system --home /nonexistent --shell /usr/sbin/nologin nats
sudo install -d -o nats -g nats -m 0750 /var/lib/nats/jetstream

Do not grant the service account write access to the whole filesystem. Its writable area should be the JetStream data path and any other directory you intentionally designate.

Write the unit file

Create /etc/systemd/system/nats-server.service. This unit uses the binary path from the installer example and includes the operational properties needed for restart, reload and JetStream writes:

[Unit]
Description=NATS Server
After=network-online.target

[Service]
Type=simple
User=nats
Group=nats
ExecStart=/usr/local/bin/nats-server -c /etc/nats-server.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s SIGUSR2 $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=800000
NoNewPrivileges=true
ProtectSystem=strict
PrivateTmp=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
ReadWritePaths=/var/lib/nats

[Install]
WantedBy=multi-user.target

ProtectSystem=strict makes the host filesystem read-only to the service, while ReadWritePaths=/var/lib/nats explicitly permits JetStream writes. NoNewPrivileges, PrivateTmp and restricted address families reduce the impact of a compromised process. If your configuration uses another data directory, update ReadWritePaths to match it. If the package installed the executable elsewhere, change ExecStart to the verified path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Enable, start and inspect the service

  1. Reload unit definitions:
sudo systemctl daemon-reload
  1. Enable NATS at boot and start it now:
sudo systemctl enable --now nats-server
  1. Check service state:
sudo systemctl status nats-server
  1. Read the most recent service log entries:
sudo journalctl -u nats-server -e

Use systemctl is-active nats-server for a script-friendly health check. A service that repeatedly restarts usually has a configuration parse error, an occupied port, an unreadable key, or a data directory that the nats user cannot write.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Install the NATS CLI and create a context

The CLI provides publish/subscribe checks plus JetStream, key-value, object-store, service, monitoring and context-management commands. Its documented Linux installer is:

curl -sf https://binaries.nats.dev/nats-io/natscli/nats@latest | sh
sudo install -m 0755 nats /usr/local/bin/nats

The endpoint is https://binaries.nats.dev/nats-io/natscli/nats@latest. Pin the CLI version for production in the same way as the server. Add a named local context:

nats context add localhost --description "Localhost"

For a secured deployment, configure that context with credentials rather than putting passwords in shell history. Then test a message:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
nats pub hello "Hello NATS!"

Run a subscriber in another terminal or use the CLI’s context and monitoring commands to confirm that the client is reaching the intended listener.

Verify the finished installation

  • Release: nats-server --version reports the release you approved, ideally v2.15.1 for this guide’s current baseline.
  • Configuration: sudo nats-server -t -c /etc/nats-server.conf passes before each rollout.
  • Service: systemctl is-active nats-server returns active, and the journal shows a ready server.
  • Messaging: an authenticated CLI context can publish and subscribe on the expected subject.
  • JetStream: create or inspect a stream and confirm files are written only beneath the configured store_dir.
  • TLS: test with the CA and hostname clients will actually use; verify that a plaintext connection is rejected when TLS is required.
  • Monitoring: keep port 8222 restricted to the administrative network because monitoring access is independent of client authorization.

Troubleshoot common failures

The service will not start after a configuration edit

Run the validation command directly, then inspect the journal. Check for a missing brace, a misspelled path, a port already used by another process, or a setting placed outside its configuration block. Correct the file, validate again, and restart only after validation passes.

JetStream reports a storage or permission error

Confirm that /var/lib/nats/jetstream exists, is owned by nats:nats, and has mode 0750 or stricter. Confirm that the unit’s ReadWritePaths includes the same directory and that store_dir in the configuration uses the exact path. A hardened unit intentionally blocks writes elsewhere.

TLS clients fail during the handshake

Check that the server can read the certificate, key and CA files; that the certificate SAN matches the hostname supplied by the client; and that the client trusts the issuing CA. A plaintext client is expected to fail when the listener requires TLS. Test with the real hostname and CA rather than an IP address or a different development name.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Clients cannot connect remotely

Confirm that the listener is not restricted to 127.0.0.1 when remote access is intended, that Ubuntu firewall rules allow the chosen port, and that authentication credentials match the configured model. If TLS is enabled, use the TLS endpoint and hostname. Keep monitoring on 8222 limited even when 4222 is reachable by clients.

The server starts manually but not under systemd

Compare the manual binary path with ExecStart, then check file permissions as the nats user rather than as root. Review journalctl -u nats-server -e for denied reads, an unavailable directory, or a port conflict. Reload systemd after editing the unit with sudo systemctl daemon-reload.

Operational choices to settle before production

  • Foreground process or systemd: foreground mode is useful for development diagnostics; systemd adds boot activation, restart-on-failure, privilege isolation, journal logging and explicit storage permissions.
  • Central users or credentials/JWTs: a local authorization list is simple for a small team; credentials/JWTs are better suited to multiple accounts, rotation and delegated administration.
  • Core NATS or JetStream: choose Core NATS when transient delivery is sufficient; choose JetStream when replay, retention or durable consumers justify storage and capacity management.
  • Monitoring exposure: enabling HTTP monitoring is a separate network-access decision. Bind or firewall it for administrators instead of exposing 8222 broadly.
  • Release discipline: pin both server and CLI versions in production, retain checksums and record the architecture so an automated update cannot introduce an unreviewed binary.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.