<p>I used Nats Streaming before for my microservices based on Docker and Kubernetes and node.js but because Nats Streaming is currently being deprecated I want to migrate to NATS and NATS JetStream.</p>
<p>This is the deployment yaml config file that I used for NATS Streaming server in my k8s folder which is using by skaffold to apply and it works fine:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: nats-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nats
  template:
    metadata:
      labels:
        app: nats
    spec:
      containers:
        - name: nats
          image: nats-streaming:0.23.2
          args:
            [
              '-p',
              '4222',
              '-m',
              '8222',
              '-hbi',
              '5s',
              '-hbt',
              '5s',
              '-hbf',
              '2',
              '-SD',
              '-cid',
              'adrian',
            ]
---
apiVersion: v1
kind: Service
metadata:
  name: nats-srv
spec:
  selector:
    app: nats
  ports:
    - name: client
      protocol: TCP
      port: 4222
      targetPort: 4222
    - name: monitoring
      protocol: TCP
      port: 8222
      targetPort: 8222
</code></pre>
<p>The cluster named <code>adrian</code> and I could connect to NATS Streaming server as a client like this in my node.js application:</p>
<pre><code>import nats from 'node-nats-streaming';

const stan = nats.connect( 'adrian', 'abc', {
  url: &quot;http://localhost:4222&quot;
} );
</code></pre>
<p>Now I want to migrate to NATS and NATS JetStream. So, I changed my Kubernetes deployment config to this:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: nats-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nats
  template:
    metadata:
      labels:
        app: nats
    spec:
      containers:
        - name: nats
          image: nats
          args:
            [
              '-p',
              '4222',
              '-m',
              '8222',
              '-D',
              '-js',
              '--cluster_name',
              'adrian',
            ]
---
apiVersion: v1
kind: Service
metadata:
  name: nats-srv
spec:
  selector:
    app: nats
  ports:
    - name: client
      protocol: TCP
      port: 4222
      targetPort: 4222
    - name: monitoring
      protocol: TCP
      port: 8222
      targetPort: 8222
</code></pre>
<p>And when I try new NATS client's connect method to connect to NATS server like below:</p>
<pre><code>import { connect } from 'nats';

const natsPublisher = async () =&gt; {
  try {
    const nc = await connect( { servers: &quot;http://localhost:4222&quot; } );
    console.log(`connected to ${nc.getServer()}`);
  } catch ( error ) {
    console.log( '--- NATS ERROR: ', error )
  }
}

natsPublisher();
</code></pre>
<p>I get this error in terminal:</p>
<pre><code>--- NATS ERROR:  NatsError: CONNECTION_REFUSED
    at Function.errorForCode (E:\Projects\express-projects\adrian-microservices\nats-test\node_modules\nats\nats-base-client\error.ts:119:12)
    at NodeTransport.&lt;anonymous&gt; (E:\Projects\express-projects\adrian-microservices\nats-test\node_modules\nats\src\node_transport.ts:92:21)
    at Generator.throw (&lt;anonymous&gt;)
    at rejected (E:\Projects\express-projects\adrian-microservices\nats-test\node_modules\nats\lib\src\node_transport.js:6:65)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  code: 'CONNECTION_REFUSED',
  chainedError: Error: connect ECONNREFUSED 127.0.0.1:4222
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16) {
    errno: -4078,
    code: 'ECONNREFUSED',
    syscall: 'connect',
    address: '127.0.0.1',
    port: 4222
  }
}
</code></pre>
<p><strong>So how could I solve the issue and connect to NATS without any problem?</strong></p>
<p>Any help would be appreciated.</p>

<p>After some trials and errors and some research, I realized that it is actually better to use Helm (Kubernetes package manager) to have a complete and correct manifest for things like NATS or Kafka or ElasticSearch, etc... So, after installing Helm Kubernetes package manager you can install NATS in your Kubernetes cluster by running a command as simple as &quot;<code>helm install my-nats nats/nats</code>&quot; and then you have NATS up and running there in your Kubernetes.</p>
<p>But in this case with the manifest I came up with for NATS unlike before that it was common to connect to NATS server from node.js client using <code>localhost</code> and external access was possible, you can connect to NATS server from node.js client by using service name like this, that is perhaps even more appropriate:</p>
<pre><code>import { connect } from 'nats';

const natsPublisher = async () =&gt; {
  try {
    const nc = await connect( { servers: &quot;http://nats-srv:4222&quot; } );
    console.log( `connected to ${ nc.getServer() }` );
  } catch ( error ) {
    console.log( 'NATS ERROR: ', error )
  }
}
</code></pre>
<p>And this is my terminal logs after connecting to NATS:</p>
<pre><code>[taxonomy] Listening on port 3000!
[taxonomy] connected to nats-srv:4222
</code></pre>
<p>Hopefully, that'll be helpful for others.</p>
