Running Angular app with connection to Pond in Docker with specific store URI

We’ve written an Angular app to display and change the state of some machines.
Within this app we are using the Actyx Pond.
The app works fine in our develop environment.
Now we’ve dockerized and deployed it on an industrial PC (IPC).
The goal is to open the web app in a browser on any machine in the same network and display data from the Actyx swarm that is configured on the IPC.

When starting the app on my local browser with the IPC’s IP address, I was wondering that I received events from my locally installed Actyx OS.
The reason for that can be seen in the developer tools of my browser:

Here you can see that the Request URL is set to ws://localhost:4243/store_api

In the corresponding docker-compose.yml, I’ve tried to change this to the ActyxOS container the web page should receive the events from. The compose file looks like this:

version: "3.3"
      context: ../.
      dockerfile: sievert-messaging-spa/Dockerfile-without-build
    restart: always
      AX_STORE_URI: ws://actyx:4243/store_api
    privileged: true
      - "80:80"
  actyxos_data: {}

But the environment variable AX_STORE_URI seems to have no effect.
Is there anything else necessary in this constellation to change the URI to a specific address different from localhost?

The approach you describe works well for headless applications, but SPAs are a different matter. Sorry for the long answer, but I feel some additional context is beneficial, also for future readers having similar issues.

The communication between the SPA and Actyx happens over http/websockets between the browser and Actyx. It really should communicate with localhost. While there is the environment variable within the docker container that hosts the SPA, it is not on the machine running the browser (and JS in the browser couldn’t access the local environment anyway).

The browser talks to the server only to get the SPA, not to exchange payload data. To reap the benefits Actyx provides, you need to keep communication local - otherwise, the app would not be useful when offline.

Here’s a quick overview how the communication looks like.

There are two general approaches:

  1. Use the application only on Actyx nodes, i.e. devices w/ Actyx installed and running. This is the recommended approach if you want to emit events and not only display data.
  2. Build a ‘traditional’ web app in which only the server is an Actyx node and provides data from the swarm. Web clients can connect to it and view these data and emit events - not directly via Actyx but through said web app as an intermediary. To help implementing these kinds of solutions, @alex_AX has published an HTTP connector app that does exactly that: GitHub - actyx-contrib/actyx-http-connector

Judging from your question, I guess the app in question rather falls into the first category:

Angular app to display and change the state of some machines

In this case, you’d normally wrap the application into an Android APK or an and deploy it along with Actyx to the machines from which it will be used.
If availability is not a concern, you can also only deploy Actyx and access the app through a web browser from a machine in the same swarm as the server (which is basically what you already, inadvertently, did).

You can also emit events through that intermediary as shown here. If you decide to go down that route, bear in mind the following trade-offs:

  • If the ‘server’ Actyx node is unavailable, no client can use the app. If the client is an Actyx node itself, it can still operate.
  • All non-Actyx clients will see the state of the ‘server’ node. All events from the swarm need to be received on the ‘server’ to be visible to the clients; events only disseminate throughout the swarm if the ‘server’ is connected.

Does this make things more transparent? Shall we discuss further on how to best proceed in that specific case?

It may be required to still change the event service / store URI in certain types of Docker deployments. The Actyx Pond can be configured with the store URI to connect to in Pond.of(): Pond.of({url: '<my store uri>'},{})

1 Like

Hi @wwerner ,
thank you for the detailed information.
I think we had a misunderstanding in our use case.
To be more clear, our approach was to install an Actyx node where the SPA is running on and the user is then able to open the frontend of the SPA from any device.
For that we had to install a web server that is handling the web requests towards Actyx but we don’t need that actually.
After reading your statements, it makes totally sense to retrieve and emit data via localhost to have a distributed system as we’ve planned.
Our solution for that is the following: the system where the Actyx node is running on (an IPC with Debian installed) will get a GUI and a possibility to connect to it via RDP or something. Then the user is still able to open the frontend from any device by opening a RDP session. Additionally the IPC will have a connected monitor so the user can interact with it directly.

1 Like