Disclaimer: We don’t intend to go over Akka or Docker details, this is only our missing guide for configuring Akka on Docker. You should review the basic of both platforms for better understanding

In my previous post, Yet another sbt-docker introduction, we discussed how we can use Scala Build Tool to create dockerfiles and Docker images. It was a must have set up in our organization since we can integrate and automate the Docker processes inside our CI environment using the same tools we are used to, sbt. However, as you might suspect, that is not the end of the story. We have encountered other Docker challenges along the way that we are going to discuss today.

My team was confident enough in using Akka as a platform for distributed work and Docker as the platform to run our Actor Systems in production (or any other environment), yet it was not that easy, at least at first.

Let’s start in the same way we started few weeks backs, a simplistic app that publishes messages into the Akka cluster using the distributed publish / subscribe Akka capabilities.

Let’s take a look at the publisher code:

In here, our app loads the configuration (we will go over it next), create an actor system with it, and start the DumbTickPublisher actor which publishes a message to the cluster every ten seconds.

On the other hand, we need something to read the messages from the cluster (a subscription) and do something with those message (process them).

We have created a new app in order so it subscribes to some events in the cluster. The actor that is subscribed to the cluster events look like this:

It's works is to listen to a topic (inputTopic) and everything that comes through the topic will be transformed using the function f and published back to the cluster using the topic outputTopic.

Now, we need to start the Transformer.

This code looks very similar to the one on the publisher but here we create instances of the Transformer instead of the DumbTickPublisher.

Now we have two apps, one that sends messages to the cluster and one that reads them, so our next move is be able to run them all.

The Configuration

In here is where we have spent most of our time, mostly, because we haven’t found enough info on the docs our anywhere else online.

Let’s quickly review the config.

Something similar to this is what you will find on any online example, there are a lot of those, but still there is a missing part for running on Docker.

With the current configuration, we can in fact, start up the two applications, locally, on two different JVMs, and they will start talking to each other. Messages will be send from one to the other, not problems at all.

Hopping this is all you need, will be build two Docker images, and create a compose file that might look like this one.

We run docker-compose up and the two containers will start up. We will see the same as before, they work. No really.

The problem is that now we were hoping to be able to say:

docker-compose scale c1=5

but this cannot be done. Even though you will see the containers starting up, the Akka logs say something completely different. The nodes are not visible any longer, and the actor system falls into an irreversible failure state.

The problem is that Akka requires a special configuration to run behind a NAT or in Docker containers.

You need bind-hostname and bind-port to be added to the configuration file.

After trying many many time, we have found a configuration that works for us.

In order to the containers to talk to each other, we need to set up the hostname to the container ip and a specific port. Messages sent to this address will be translated into bind-*.

The last part is to update our compose file as follows.

Remember we need the Docker container ip (CLUSTER_IP), so we pass “” with implies it will use InetAddress.getLocalHost.getHostAddress instead, as the doc indicates. Also, we used port 0 (cero) in CLUSTER_PORT so Akka uses a random port.

After these changes, we should be able to reconstruct the Docker images (make sure the config changes get into the Docker images) and run:

docker-compose up

docker-compose scale c1=100

You will see how your actors start communicating with each other, and you will realize that you are ready to go.