NATS and Docker

NATS Server Containerization

The NATS server is provided as a Docker image on Docker Hub that you can run using the Docker daemon. The NATS server Docker image is extremely lightweight, coming in under 10 MB in size.
​Synadia actively maintains and supports the NATS server Docker image.

Usage

To use the Docker container image, install Docker and pull the public image:
1
docker pull nats
Copied!
Run the NATS server image:
1
docker run nats
Copied!
By default the NATS server exposes multiple ports:
  • 4222 is for clients.
  • 8222 is an HTTP management port for information reporting.
  • 6222 is a routing port for clustering.
  • Use -p or -P to customize.
To run a server with the ports exposed on a docker network:
First create the 'docker network' nats
1
docker network create nats
Copied!
And start the server
1
docker run --name nats --network nats --rm -p 4222:4222 -p 8222:8222 nats --http_port 8222
Copied!

Creating a NATS Cluster

First run a server with the ports exposed on the 'nats' docker network:
1
docker run --name nats --network nats --rm -p 4222:4222 -p 8222:8222 nats --http_port 8222 --cluster_name NATS --cluster nats://0.0.0.0:6222
Copied!
1
[1] 2021/09/28 09:21:56.554756 [INF] Starting nats-server
2
[1] 2021/09/28 09:21:56.554864 [INF] Version: 2.6.1
3
[1] 2021/09/28 09:21:56.554878 [INF] Git: [c91f0fe]
4
[1] 2021/09/28 09:21:56.554894 [INF] Name: NDIQLLD2UGGPSAEYBKHW3S2JB2DXIAFHMIWWRUBAX7FC4RTQX4ET2JNQ
5
[1] 2021/09/28 09:21:56.555001 [INF] ID: NDIQLLD2UGGPSAEYBKHW3S2JB2DXIAFHMIWWRUBAX7FC4RTQX4ET2JNQ
6
[1] 2021/09/28 09:21:56.557658 [INF] Starting http monitor on 0.0.0.0:8222
7
[1] 2021/09/28 09:21:56.557967 [INF] Listening for client connections on 0.0.0.0:4222
8
[1] 2021/09/28 09:21:56.559224 [INF] Server is ready
9
[1] 2021/09/28 09:21:56.559375 [INF] Cluster name is NATS
10
[1] 2021/09/28 09:21:56.559433 [INF] Listening for route connections on 0.0.0.0:6222
Copied!
Next, start another couple of servers and point them to the seed server to make them form a cluster:
1
docker run --name nats-1 --network nats --rm nats --cluster_name NATS --cluster nats://0.0.0.0:6222 --routes=nats://ruser:[email protected]:6222
2
docker run --name nats-2 --network nats --rm nats --cluster_name NATS --cluster nats://0.0.0.0:6222 --routes=nats://ruser:[email protected]:6222
Copied!
NOTE Since the Docker image protects routes using credentials we need to provide them above. Extracted from Docker image configuration​
To verify the routes are connected, you can make a request to the monitoring endpoint on /routez as follows and confirm that there are now 2 routes:
1
curl http://127.0.0.1:8222/routez
Copied!
1
{
2
"server_id": "NDIQLLD2UGGPSAEYBKHW3S2JB2DXIAFHMIWWRUBAX7FC4RTQX4ET2JNQ",
3
"now": "2021-09-28T09:22:15.8019785Z",
4
"num_routes": 2,
5
"routes": [
6
{
7
"rid": 5,
8
"remote_id": "NBRAUY3YSVFYU7BFWI2YF5VPQFGO2XCKKAHYZ7ETCMGB3SQY3FDFTYOQ",
9
"did_solicit": false,
10
"is_configured": false,
11
"ip": "172.18.0.3",
12
"port": 59092,
13
"pending_size": 0,
14
"rtt": "1.2505ms",
15
"in_msgs": 4,
16
"out_msgs": 3,
17
"in_bytes": 2714,
18
"out_bytes": 1943,
19
"subscriptions": 35
20
},
21
{
22
"rid": 6,
23
"remote_id": "NA5STTST5GYFCD22M2I3VDJ57LQKOU35ZVWKQY3O5QRFGOPC3RFDIDVJ",
24
"did_solicit": false,
25
"is_configured": false,
26
"ip": "172.18.0.4",
27
"port": 47424,
28
"pending_size": 0,
29
"rtt": "1.2008ms",
30
"in_msgs": 4,
31
"out_msgs": 1,
32
"in_bytes": 2930,
33
"out_bytes": 833,
34
"subscriptions": 35
35
}
36
]
37
}
Copied!

Creating a NATS Cluster with Docker Compose

It is also straightforward to create a cluster using Docker Compose. Below is a simple example that uses a network named nats to create a full mesh cluster.
1
version: "3.5"
2
services:
3
nats:
4
image: nats
5
ports:
6
- "8222:8222"
7
command: "--cluster_name NATS --cluster nats://0.0.0.0:6222 --http_port 8222 "
8
networks: ["nats"]
9
nats-1:
10
image: nats
11
command: "--cluster_name NATS --cluster nats://0.0.0.0:6222 --routes=nats://ruser:[email protected]:6222"
12
networks: ["nats"]
13
depends_on: ["nats"]
14
nats-2:
15
image: nats
16
command: "--cluster_name NATS --cluster nats://0.0.0.0:6222 --routes=nats://ruser:[email protected]:6222"
17
networks: ["nats"]
18
depends_on: ["nats"]
19
​
20
networks:
21
nats:
22
name: nats
Copied!
Now we use Docker Compose to create the cluster that will be using the nats network:
1
docker-compose -f nats-cluster.yaml up
Copied!
1
[+] Running 3/3
2
â ¿ Container xxx_nats_1 Created
3
â ¿ Container xxx_nats-1_1 Created
4
â ¿ Container xxx_nats-2_1 Created
5
Attaching to nats-1_1, nats-2_1, nats_1
6
nats_1 | [1] 2021/09/28 10:42:36.742844 [INF] Starting nats-server
7
nats_1 | [1] 2021/09/28 10:42:36.742898 [INF] Version: 2.6.1
8
nats_1 | [1] 2021/09/28 10:42:36.742913 [INF] Git: [c91f0fe]
9
nats_1 | [1] 2021/09/28 10:42:36.742929 [INF] Name: NCZIIQ6QT4KT5K5WBP7H2RRBM4MSYD4C2TVSRZOZN57EHX6VTF4EWXAU
10
nats_1 | [1] 2021/09/28 10:42:36.742954 [INF] ID: NCZIIQ6QT4KT5K5WBP7H2RRBM4MSYD4C2TVSRZOZN57EHX6VTF4EWXAU
11
nats_1 | [1] 2021/09/28 10:42:36.745289 [INF] Starting http monitor on 0.0.0.0:8222
12
nats_1 | [1] 2021/09/28 10:42:36.745737 [INF] Listening for client connections on 0.0.0.0:4222
13
nats_1 | [1] 2021/09/28 10:42:36.750381 [INF] Server is ready
14
nats_1 | [1] 2021/09/28 10:42:36.750669 [INF] Cluster name is NATS
15
nats_1 | [1] 2021/09/28 10:42:36.751444 [INF] Listening for route connections on 0.0.0.0:6222
16
nats-1_1 | [1] 2021/09/28 10:42:37.709888 [INF] Starting nats-server
17
nats-1_1 | [1] 2021/09/28 10:42:37.709977 [INF] Version: 2.6.1
18
nats-1_1 | [1] 2021/09/28 10:42:37.709999 [INF] Git: [c91f0fe]
19
nats-1_1 | [1] 2021/09/28 10:42:37.710023 [INF] Name: NBHTXXY3HYZVPXITYQ73BSDA5CQZINTKYRM23XFI46RWWTTUP5TAXQMB
20
nats-1_1 | [1] 2021/09/28 10:42:37.710042 [INF] ID: NBHTXXY3HYZVPXITYQ73BSDA5CQZINTKYRM23XFI46RWWTTUP5TAXQMB
21
nats-1_1 | [1] 2021/09/28 10:42:37.711646 [INF] Listening for client connections on 0.0.0.0:4222
22
nats-1_1 | [1] 2021/09/28 10:42:37.712197 [INF] Server is ready
23
nats-1_1 | [1] 2021/09/28 10:42:37.712376 [INF] Cluster name is NATS
24
nats-1_1 | [1] 2021/09/28 10:42:37.712469 [INF] Listening for route connections on 0.0.0.0:6222
25
nats_1 | [1] 2021/09/28 10:42:37.718918 [INF] 172.18.0.4:52950 - rid:4 - Route connection created
26
nats-1_1 | [1] 2021/09/28 10:42:37.719906 [INF] 172.18.0.3:6222 - rid:4 - Route connection created
27
nats-2_1 | [1] 2021/09/28 10:42:37.731357 [INF] Starting nats-server
28
nats-2_1 | [1] 2021/09/28 10:42:37.731518 [INF] Version: 2.6.1
29
nats-2_1 | [1] 2021/09/28 10:42:37.731531 [INF] Git: [c91f0fe]
30
nats-2_1 | [1] 2021/09/28 10:42:37.731543 [INF] Name: NCG6UQ2N3IHE6OS76TL46RNZBAPHNUCQSA64FDFHG5US2LLJOQLD5ZK2
31
nats-2_1 | [1] 2021/09/28 10:42:37.731554 [INF] ID: NCG6UQ2N3IHE6OS76TL46RNZBAPHNUCQSA64FDFHG5US2LLJOQLD5ZK2
32
nats-2_1 | [1] 2021/09/28 10:42:37.732893 [INF] Listening for client connections on 0.0.0.0:4222
33
nats-2_1 | [1] 2021/09/28 10:42:37.733431 [INF] Server is ready
34
nats-2_1 | [1] 2021/09/28 10:42:37.733491 [INF] Cluster name is NATS
35
nats-2_1 | [1] 2021/09/28 10:42:37.733835 [INF] Listening for route connections on 0.0.0.0:6222
36
nats_1 | [1] 2021/09/28 10:42:37.740860 [INF] 172.18.0.5:54616 - rid:5 - Route connection created
37
nats-2_1 | [1] 2021/09/28 10:42:37.741557 [INF] 172.18.0.3:6222 - rid:4 - Route connection created
38
nats-1_1 | [1] 2021/09/28 10:42:37.743981 [INF] 172.18.0.5:6222 - rid:5 - Route connection created
39
nats-2_1 | [1] 2021/09/28 10:42:37.744332 [INF] 172.18.0.4:40250 - rid:5 - Route connection created
Copied!

Testing the Clusters

Now, the following should work: make a subscription on one of the nodes and publish it from another node. You should be able to receive the message without problems.
1
docker run --network nats --rm -it synadia/nats-box
Copied!
Inside the container
1
nats sub -s nats://nats:4222 hello &
2
nats pub -s "nats://nats-1:4222" hello first
3
nats pub -s "nats://nats-2:4222" hello second
Copied!
Also stopping the seed node to which the subscription was done, should trigger an automatic failover to the other nodes:
1
docker-compose -f nats-cluster.yaml stop nats
Copied!
Output extract
1
...
2
16e55f1c4f3c:~# 10:47:28 Disconnected due to: EOF, will attempt reconnect
3
10:47:28 Disconnected due to: EOF, will attempt reconnect
4
10:47:28 Reconnected [nats://172.18.0.4:4222]
Copied!
Publishing again will continue to work after the reconnection:
1
nats pub -s "nats://nats-1:4222" hello again
2
nats pub -s "nats://nats-2:4222" hello again
Copied!

Tutorial

See the NATS Docker tutorial for more instructions on using the NATS server Docker image.
Last modified 11d ago