
Deploy NATS | (Just Updated) JetStream Streams Survive Redeploys, Locked Behind A Password
NATS JetStream broker. Password on, streams kept on a volume, public URL
Just deployed
/data
Deploy and Host NATS on Railway
NATS is a lightweight, high-performance messaging system for microservices, IoT and edge workloads. With JetStream switched on it also stores messages: durable streams, replay, consumers with acknowledgements, key-value buckets and object stores, all from one small binary.
This template runs NATS 2.15 as a single service from a digest-pinned official image: the client port on a Railway TCP proxy, the monitoring port on the private network, and a Railway volume holding every JetStream stream.
About Hosting NATS
- JetStream is on and its data survives redeploys. The stock
natsimage starts with JetStream off and no volume, so streams, key-value buckets and consumers do not exist or vanish with the container. Here the store lives on the volume at/data; a stream with messages in it was read back intact after a redeploy. - A password is required from the first connection. A username and password are generated per
deploy; anonymous clients and wrong passwords get
Authorization Violation. - Limits follow your plan. The start command reads the container's memory limit and the volume's size and sets the JetStream memory and file store limits from them (50% of memory, 90% of the disk), instead of letting the server size itself from the host.
- Two ways in. Services in the same project connect with the private URL; clients elsewhere
use the TCP proxy URL. The monitoring endpoint (
/jsz,/varz) stays on the private network.
Common Use Cases
- A message bus between microservices: request/reply, pub/sub and queue groups
- Durable work queues and event streams with replay, using JetStream consumers
- Key-value and object storage next to your messaging, without another database
- Lightweight telemetry ingestion from devices and edge clients
Dependencies for NATS Hosting
- One Railway volume for JetStream data (created by the template)
Deployment Dependencies
- NATS documentation: https://docs.nats.io
- JetStream: https://docs.nats.io/nats-concepts/jetstream
- Official image: https://hub.docker.com/_/nats
Implementation Details
| Variable | Purpose |
|---|---|
NATS_USER | Username for connections, generated per deploy. |
NATS_PASSWORD | Password for connections, generated per deploy. |
NATS_PRIVATE_URL | nats:// URL on the private network, for services in the same project. |
NATS_PUBLIC_URL | nats:// URL on the TCP proxy, for clients outside Railway. |
NATS_MONITORING_PRIVATE_URL | HTTP monitoring endpoint on the private network. |
Python (nats-py):
import asyncio, nats
async def main():
nc = await nats.connect("")
js = nc.jetstream()
await js.add_stream(name="EVENTS", subjects=["events.>"])
await js.publish("events.signup", b"hello")
asyncio.run(main())
Why Deploy NATS on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying NATS on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
Template Content