• December 31, 2025

How to Deploy NATS – High-Performance Messaging

How to Deploy NATS – High-Performance Messaging

Deploy NATS with Docker Compose, JetStream persistence, secure authentication, and verified client connectivity.

NATS is a lightweight, high-performance messaging system designed for distributed and cloud-native applications. It supports publish-subscribe, request-reply, and streaming workloads through JetStream. NATS is widely used for microservices communication, event-driven systems, IoT messaging, and real-time data pipelines.

This article explains how to deploy NATS using Docker Compose, enable JetStream persistence, configure authentication and authorization, and verify client connectivity using the NATS CLI.

Prerequisites

Before you begin, you need to:

  • Have access to an Ubuntu 24.04-based server as a non-root user with sudo privileges.
  • Install Docker and Docker Compose.

Set Up the Directory Structure and Environment Variables

In this section, you create the required directory structure for NATS and define environment variables in a .env file that Docker Compose loads automatically.

  1. Create the project directory.
    console
    $ mkdir -p ~/nats-stack/{data,config}
  2. Navigate into the project directory.
    console
    $ cd ~/nats-stack
  3. Create and edit the .env file.
    console
    $ nano .env

    Add the following variables:

    ini
    NATS_CLIENT_PORT=4222
    NATS_CLUSTER_PORT=6222

    Replace:

    • NATS_CLIENT_PORT with the client connection port.
    • NATS_CLUSTER_PORT with the cluster communication port.

    Save and close the file.

Install NATS CLI and Create the NATS Configuration

In this section, you install the NATS CLI, generate secure credentials, and configure NATS with JetStream, authentication, and authorization.

  1. Download the NATS CLI binary.
    console
    $ curl -sf https://binaries.nats.dev/nats-io/natscli/nats@latest | sh
  2. Move the binary into your system PATH.
    console
    $ sudo mv nats /usr/local/bin/
  3. Verify the installation.
    console
    $ nats --version
  4. Generate a password hash for the system or application user.
    console
    $ nats server passwd

    Enter the password twice and copy the generated hash.

    Your output should be similar to the one below:

    $2a$11$C6sj6xxxxx....

    Repeat this step for each user you want to define.

  5. Create the NATS configuration file.
    console
    $ nano config/nats.conf

    Add the following configuration:

    ini
    # Client port
    port: 4222
    monitor_port: 8222
    server_name: "NATS_SERVER_NAME"
    
    # System account
    system_account: SYS
    
    accounts {
      SYS {
        users = [
          { user: "sysadmin", password: "SYSTEM_PASSWORD_HASH" }
        ]
      }
    }
    
    # JetStream
    jetstream {
      store_dir: "/data/jetstream"
      max_mem_store: 1GB
      max_file_store: 5GB
    }
    
    authorization {
      default_permissions = {
        publish = "SANDBOX.*"
        subscribe = ["PUBLIC.>", "_INBOX.>"]
      }
      ADMIN = {
        publish = ">"
        subscribe = ">"
      }
      users = [
        {user: USERNAME, password: "USER_PASSWORD_HASH", permissions: $ADMIN}
      ]
    }

    In the above configuration:

    • server_name identifies the NATS server in logs, monitoring output, and system events.
    • system_account enables internal system features required for monitoring and JetStream management.
    • accounts defines authentication boundaries for system and application users.
    • authorization enforces subject-level access control, with an admin permission set that grants full publish and subscribe access.
    • JetStream enables message persistence with defined memory and disk limits.

    Replace the following values before starting the service:

    • NATS_SERVER_NAME with a descriptive server name.
    • SYSTEM_PASSWORD_HASH with the bcrypt hash generated for the system user.
    • USERNAME with your application user name.
    • USER_PASSWORD_HASH with the bcrypt hash generated for the application user.

    Save and close the file.

Deploy with Docker Compose

In this section, you create the Docker Compose manifest that deploys NATS with JetStream persistence and monitoring enabled.

  1. Create the Docker Compose manifest.
    console
    $ nano docker-compose.yaml

    Add the following content:

    yaml
    services:
      nats:
        image: nats:2.12
        container_name: nats
        command:
          - "-c"
          - "/etc/nats/nats.conf"
    
        ports:
          - "${NATS_CLIENT_PORT}:4222"
          - "${NATS_CLUSTER_PORT}:6222"
    
        volumes:
          - "./data:/data"
          - "./config/nats.conf:/etc/nats/nats.conf:ro"
    
        restart: unless-stopped
    
        healthcheck:
          test: ["CMD", "nats", "server", "ping"]
          interval: 10s
          timeout: 5s
          retries: 5

    Save and close the file.

    In this manifest:

    • image: Uses the official NATS 2.12 image.
    • command: Loads the custom NATS configuration at startup.
    • ports:
      • 4222: Client connections.
      • 8222: Monitoring endpoint (localhost only).
      • 6222: Cluster communication.
    • volumes:
      • ./data: Persists JetStream messages.
      • ./config/nats.conf: Injects the server configuration.
    • healthcheck: Confirms the server responds to pings.
    • restart: unless-stopped: Restarts the service automatically.
  2. Start the NATS service.
    console
    $ docker compose up -d
  3. Verify that the NATS service is running.
    console
    $ docker compose ps

    Ensure that the output shows the NATS container is healthy and running.

  4. View logs if needed.
    console
    $ docker compose logs

    For more information on managing a Docker Compose stack, see the How To Use Docker Compose article.

Verify NATS Connectivity

In this section, you verify that the NATS server is reachable and accepting client connections.

Test connectivity using the NATS CLI.

console
$ nats --server nats://sysadmin:SYS_USER_PASSWORD@SERVER_IP:4222 server ping

Replace SYS_USER_PASSWORD and SERVER_IP with the system user password and server IP.

Output:

NATS_SERVER_NAME                                             rtt=338.443125ms

---- ping statistics ----
1 replies max: 338.00 min: 338.00 avg: 338.00

Successful output confirms that the NATS server is reachable and authenticated correctly.

Conclusion

You successfully deployed NATS using Docker Compose with JetStream persistence enabled. You configured secure authentication and authorization, enabled persistent message storage, exposed the required messaging and verified client connectivity using the NATS CLI.

Leave a Reply

Your email address will not be published. Required fields are marked *