Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsiTechGuides 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
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
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.
- 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
natsaccount 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.
#1 Best Overall
| 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
- Change to a temporary working directory and run the documented installer:
curl -sf https://binaries.nats.dev/nats-io/nats-server/v2@latest | sh
- Install the binary in a system path:
sudo install -m 0755 nats-server /usr/local/bin/nats-server
- 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.
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.
For a development-only monitoring test, start the server with:
Rank #2
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.
Recommended Free Tools
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.
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:
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →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.confbefore 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.
Rank #4
| 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.
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.
Enable, start and inspect the service
- Reload unit definitions:
sudo systemctl daemon-reload
- Enable NATS at boot and start it now:
sudo systemctl enable --now nats-server
- Check service state:
sudo systemctl status nats-server
- 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.
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:
Best Value
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:
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 --versionreports the release you approved, ideally v2.15.1 for this guide’s current baseline. - Configuration:
sudo nats-server -t -c /etc/nats-server.confpasses before each rollout. - Service:
systemctl is-active nats-serverreturnsactive, 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.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Clients 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.
Quick Recap
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.

