NATS es un sistema de mensajería ligero escrito en Go que ofrece publicación/suscripción, request-reply y colas de trabajo con latencias de microsegundos y un único binario sin dependencias. Su capa JetStream añade persistencia: streams que guardan mensajes en disco y consumidores que los leen con confirmación. En este tutorial instalarás NATS Server en Ubuntu 24.04 como servicio systemd, lo configurarás con autenticación y JetStream, y probarás los patrones principales con la CLI oficial nats.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS de 64 bits (x86_64), por ejemplo un VPS de CubePath, con al menos 1 GB de RAM.
- Un usuario no root con privilegios
sudo. - UFW activo con SSH permitido.
Paso 1: Instalar NATS Server
NATS Server se distribuye como un binario estático en las releases de GitHub. Consulta la última versión estable en la página de releases de nats-io/nats-server y ajusta la variable:
NATS_VERSION=2.11.0
cd /tmp
curl -fLO "https://github.com/nats-io/nats-server/releases/download/v${NATS_VERSION}/nats-server-v${NATS_VERSION}-linux-amd64.tar.gz"
Comprueba el hash del archivo con sha256sum y compáralo con el que aparece en el archivo SHA256SUMS de la misma release:
sha256sum "nats-server-v${NATS_VERSION}-linux-amd64.tar.gz"
Extrae el binario e instálalo en /usr/local/bin:
tar -xzf "nats-server-v${NATS_VERSION}-linux-amd64.tar.gz"
sudo install -m 0755 "nats-server-v${NATS_VERSION}-linux-amd64/nats-server" /usr/local/bin/nats-server
Verifica la instalación:
nats-server --version
nats-server: v2.11.0
Paso 2: Instalar la CLI de NATS
La CLI nats sirve para publicar, suscribirse, gestionar streams y consultar el estado del servidor. El proyecto ofrece un script que descarga el binario compilado para tu plataforma en el directorio actual. Descárgalo primero, revísalo y ejecútalo:
cd /tmp
curl -sf https://binaries.nats.dev/nats-io/natscli/nats@latest -o install-nats-cli.sh
less install-nats-cli.sh
sh install-nats-cli.sh
sudo install -m 0755 nats /usr/local/bin/nats
Comprueba que funciona:
nats --version
Paso 3: Crear el usuario y los directorios
Ejecuta NATS con un usuario de sistema sin privilegios y crea los directorios de configuración y de datos de JetStream:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin nats
sudo install -d -m 0755 /etc/nats
sudo install -d -o nats -g nats -m 0750 /var/lib/nats/jetstream
Paso 4: Configurar NATS con autenticación y JetStream
No guardes contraseñas en claro en la configuración. La CLI genera un hash bcrypt a partir de la contraseña que escribas:
nats server passwd
? Enter password [? for help] ********************
? Reenter password [? for help] ********************
$2a$11$Ra9Jr0...
Guarda la contraseña en tu gestor de contraseñas y copia el hash. Repite el comando para un segundo usuario de administración. Después crea el archivo de configuración:
sudo nano /etc/nats/nats-server.conf
server_name: nats-1
# Puerto de clientes
listen: 0.0.0.0:4222
# Endpoint HTTP de monitorización, solo en local
http: 127.0.0.1:8222
jetstream {
store_dir: /var/lib/nats/jetstream
max_memory_store: 256MB
max_file_store: 10GB
}
accounts {
APP {
jetstream: enabled
users: [
{ user: app, password: "$2a$11$hash_del_usuario_app" }
]
}
SYS {
users: [
{ user: admin, password: "$2a$11$hash_del_usuario_admin" }
]
}
}
system_account: SYS
max_payload: 1MB
Qué define esta configuración:
- La cuenta
APPes un espacio aislado de mensajes para tu aplicación, con JetStream habilitado. Los usuarios de una cuenta no ven los subjects de otra. - La cuenta
SYSes la cuenta de sistema: su usuario puede consultar el estado del servidor y de JetStream con la CLI. max_memory_storeymax_file_storelimitan cuánto pueden ocupar los streams en memoria y en disco.max_payloades el tamaño máximo de un mensaje. NATS está pensado para mensajes pequeños; para archivos grandes guarda el archivo en otro sitio y envía la referencia.
Protege el archivo, porque contiene los hashes:
sudo chown root:nats /etc/nats/nats-server.conf
sudo chmod 0640 /etc/nats/nats-server.conf
Comprueba que la sintaxis es correcta:
sudo -u nats nats-server -t -c /etc/nats/nats-server.conf
Si hay un error, el comando indica el archivo y la línea donde está; si no, termina sin mostrar errores.
Paso 5: Crear el servicio systemd
sudo nano /etc/systemd/system/nats.service
[Unit]
Description=NATS Server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=nats
Group=nats
ExecStart=/usr/local/bin/nats-server -c /etc/nats/nats-server.conf
ExecReload=/bin/kill -s HUP $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
ExecReload envía la señal HUP, con la que NATS recarga la configuración (por ejemplo, usuarios nuevos) sin cortar conexiones. Arranca el servicio:
sudo systemctl daemon-reload
sudo systemctl enable --now nats
systemctl status nats --no-pager
Revisa el log de arranque:
sudo journalctl -u nats -n 20 --no-pager
[INF] Starting nats-server
[INF] Version: 2.11.0
[INF] Starting JetStream
[INF] Starting http monitor on 127.0.0.1:8222
[INF] Listening for client connections on 0.0.0.0:4222
[INF] Server is ready
Consulta también el endpoint de salud:
curl -s http://127.0.0.1:8222/healthz
{"status":"ok"}
Paso 6: Configurar contextos en la CLI
Los contextos guardan servidor y credenciales para no repetirlos en cada comando. Crea uno para la aplicación y otro para el administrador, con las contraseñas en claro que generaste en el paso 4:
nats context save app --server nats://127.0.0.1:4222 --user app --password 'your_app_password' --select
nats context save sys --server nats://127.0.0.1:4222 --user admin --password 'your_admin_password'
Comprueba la conexión con el contexto activo (app):
nats account info
La salida muestra la cuenta APP conectada y el apartado de JetStream con los límites de memoria y disco.
Paso 7: Probar publicación/suscripción y request-reply
En NATS los mensajes se publican en subjects jerárquicos separados por puntos. El comodín * sustituye un nivel y > uno o más niveles al final.
Abre una segunda sesión SSH y suscríbete a todos los eventos de pedidos:
nats sub 'orders.>'
En la primera sesión, publica un mensaje:
nats pub orders.created '{"order_id": 1, "total": 19.90}'
En la sesión suscrita aparecerá:
[#1] Received on "orders.created"
{"order_id": 1, "total": 19.90}
Los mensajes de NATS básico no se guardan: si no hay nadie suscrito en ese momento, el mensaje se pierde. Para repartir trabajo entre varias instancias de un servicio, suscríbelas a un grupo de cola con --queue; cada mensaje llega solo a una de ellas:
nats sub 'orders.>' --queue workers
Para request-reply, deja un servicio respondiendo en la segunda sesión (detén antes la suscripción con Ctrl+C):
nats reply 'inventory.check' '{"available": true}'
Y envía una petición desde la primera:
nats request inventory.check '{"sku": "ABC-123"}'
Received with rtt 412µs
{"available": true}
Paso 8: Guardar mensajes con JetStream
Un stream de JetStream captura los mensajes publicados en unos subjects y los conserva según su política de retención, aunque no haya consumidores conectados. Crea un stream ORDERS que guarde en disco todo lo publicado en orders.> durante 7 días:
nats stream add ORDERS --subjects 'orders.>' --storage file --retention limits \
--max-age 7d --discard old --replicas 1 --defaults
Publica tres mensajes y consulta el stream:
for i in 1 2 3; do nats pub orders.created "{\"order_id\": $i}"; done
nats stream info ORDERS
State:
Messages: 3
Bytes: 213 B
First Sequence: 1 @ 2026-09-25 10:20:01 UTC
Last Sequence: 3 @ 2026-09-25 10:20:01 UTC
Active Consumers: 0
Crea un consumidor duradero de tipo pull. Recuerda su posición y exige confirmación explícita de cada mensaje:
nats consumer add ORDERS billing --pull --deliver all --ack explicit --defaults
Lee y confirma los mensajes pendientes:
nats consumer next ORDERS billing --count 3
[10:21:14] subj: orders.created / tries: 1 / cons seq: 1 / str seq: 1 / pending: 2
{"order_id": 1}
Acknowledged message
...
Si vuelves a ejecutar el comando, no quedarán mensajes pendientes para billing, pero los mensajes siguen en el stream hasta que caduquen. Otro consumidor nuevo podría leerlos desde el principio.
Con el contexto de sistema puedes ver el uso de JetStream del servidor:
nats server report jetstream --context sys
Paso 9: Abrir el puerto a los clientes
Permite el puerto 4222 solo desde las IPs de tus aplicaciones:
sudo ufw allow from app_server_ip to any port 4222 proto tcp
sudo ufw status
El puerto 8222 de monitorización escucha solo en 127.0.0.1 y no necesita regla.
Advertenciasin TLS, las credenciales y los mensajes viajan en claro. Si los clientes se conectan por Internet y no por una red privada, añade un bloque
tls { cert_file: "/etc/nats/certs/server.crt", key_file: "/etc/nats/certs/server.key" }a la configuración con un certificado válido para tu dominio.
Formar un clúster de tres nodos
Para alta disponibilidad, repite la instalación en tres servidores de la misma red privada y añade un bloque cluster a cada configuración. Cada nodo necesita un server_name distinto (nats-1, nats-2, nats-3) y las mismas cuentas:
cluster {
name: nats-cluster
listen: 0.0.0.0:6222
routes: [
nats-route://10.0.0.11:6222
nats-route://10.0.0.12:6222
nats-route://10.0.0.13:6222
]
}
Abre el puerto 6222 solo entre los nodos:
sudo ufw allow from 10.0.0.0/24 to any port 6222 proto tcp
Tras reiniciar los tres servicios, nats server list --context sys debe mostrar los tres servidores. Los streams creados con --replicas 3 se replican en los tres nodos y siguen disponibles si cae uno. Los clientes deben recibir la lista de los tres servidores (nats://10.0.0.11:4222,nats://10.0.0.12:4222,nats://10.0.0.13:4222) para reconectar a otro nodo automáticamente.
Solución de problemas
Authorization Violational conectar: usuario o contraseña incorrectos. Recuerda que en la configuración va el hash bcrypt y en el cliente la contraseña en claro.JetStream not enabled for account: faltajetstream: enableden la cuenta del usuario o el bloquejetstreamdel servidor.- El servicio no arranca con un error de permisos en
/var/lib/nats/jetstream: el directorio debe pertenecer al usuarionats. Corrígelo consudo chown -R nats:nats /var/lib/nats. Maximum Payload Violation: el mensaje superamax_payload. Reduce el tamaño del mensaje en lugar de subir el límite.
Conclusión
Tienes NATS Server funcionando como servicio systemd con autenticación por cuentas, contraseñas en bcrypt, JetStream en disco y la monitorización restringida a localhost, y has probado pub/sub, grupos de cola, request-reply y consumidores persistentes. Como siguientes pasos, añade TLS a las conexiones de clientes, forma un clúster de tres nodos con streams replicados y conecta tus servicios con una de las librerías oficiales (Go, Python nats-py, Node.js, Java o Rust).
