Running Actyx app in Docker using Event Service

We’ve created two apps in Node.JS: one for connecting to SIMATIC PLCs and creating events using the Pond, one for retrieving the events using the event service client and inserting them into a Postgres database.
Both are running properly, but when trying to start them in a Docker environment (no nested Docker containers), the one that’s using the event service client is throwing the following message:

Error: connect ECONNREFUSED [127.0.0.1:4454](http://127.0.0.1:4454)

at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1107:14)

errno: 'ECONNREFUSED',

code: 'ECONNREFUSED',

syscall: 'connect',

address: '127.0.0.1',

port: 4454

It’s trying to connect to the Pond using localhost via port 4454. In a Docker compose file, this port is exposed:

actyx:

    image: actyx/os:1.1.5

    privileged: true

    ports:

      - '4001:4001'

      - '4243:4243'

      - '4454:4454'

      - '4457:4457'

      - '8080:8080'

    volumes:

      - actyxos_data:/data

  postgres-exporter:

    build:

      context: .

      dockerfile: ./src/postgres-exporter/Dockerfile

    restart: always

    depends_on:

      - actyx

    privileged: true

    environment:

      PG_USER: postgres

      PG_HOST: postgresdb

      PG_DATABASE: postgres

      PG_PASSWORD: Focus2020

      PG_PORT: 5432

      AX_STORE_URI: ws://actyx:4243/store_api

The env variable “AX_STORE_URI” is used in another compose file that’s starting the PLC connector using the Pond. Here it was necessary to declare the store URI so that the app is not trying to connect via localhost. In case of using the event service client, this env variable is not working. Is there possibly another variable I’ll need to get this container up and running?

Additionally here are some code snippets of how the apps are using the pond resp. the event service client:

PLC connector (working with env variable AX_STORE_URI):

Pond.default()
  .then((pond) => main(pond, getSettings()))
  .catch((err) => {
    console.error(err)
    process.exit(6) // assume we're restarting the app automatically
  })

Postgres exporter (not running in Docker environment):

import { Client, OffsetMap, Ordering, Event } from '@actyx/os-sdk'

[...]

const main = async () => {
  const eventService = Client().eventService // used to subscribe on events from the Pond
  const pg = await dbInit(exitApp) // connecting Postgres (works)

[...]

const bulkInsert = async (lowerBound: OffsetMap) => {
    queryActive = true
    let eventList: Array<Event> = []
    const current = await eventService.offsetsPromise()
    eventService.query({
      lowerBound,
      upperBound: current,
      ordering: Ordering.Lamport,
      subscriptions: [{}],
      onEvent: (event: Event) => { 
          [...]
      }
}

Hi @alko,

this is due to the fact that the event service interacts directly with the event API, as opposed to the store api for the pond.
You need to configure it separately using the AX_EVENT_SERVICE_URI environment variable.
I attached a sample project using Pond to emit events and a plain event service subscription to receive them.

Example docker-compose.yml below.

Does this work for you?

version: '3.3'
services:
  actyx:
    image: actyx/os:1.1.5
    privileged: true
    ports:
      - '4001:4001'
      - '4243:4243'
      - '4454:4454'
      - '4457:4457'
      - '8080:8080'
    volumes:
      - actyxos_data:/data
    environment:
      AX_STORE_URI: ws://actyx:4243/store_api  
  
  test-app:
    build:
      context: .
      dockerfile: ./src/test/Dockerfile
    restart: always
    depends_on:
      - actyx
    environment:
      AX_STORE_URI: ws://actyx:4243/store_api
      AX_EVENT_SERVICE_URI: http://actyx:4454/api
    privileged: true
volumes:
  actyxos_data: {}

To run the sample, execute …

  • $ npm install
  • $ npm run node:test:build
  • $ docker compose build
  • $ docker compose up
    … in the project root.

sample.zip (58.1 KB)

1 Like

Hi @wwerner ,

thank you for the quick response!
That’s exactly what I needed here!

Kind regards

1 Like