Wednesday, April 13, 2016

Dockerizing Lightstreamer

Containerization is one of the most important IT trends over the last two years. Docker heads this technology up, providing an open platform which lets you package up applications with all their dependencies. Applications can be shipped as software containers to enable process isolation, resources optimization, portability, and ease of maintainability and deployment.

As passionate about each new exciting and promising technology, we at Lightstreamer could not miss the opportunity to enter this world, so we tested how well our Server could be "dockerized" and ... Yes, we did it! We published the Docker official image for Lightsteamer Server on Docker Hub.

The aim of this blog post is to show how to use our Docker image as a starting point to build new Lightstreamer Server deployments.

Getting Started

First of all, download and install Docker by following the instructions relative to your specific system. After you have installed and started the Docker service, download the Lightstreamer image from Docker Hub through the command:
Shortly after, you should see dynamic information about download progress, until the image will be completely downloaded and installed, as follows:
To verify your downloaded succeeded, check the availability of the image through the docker images command, which lists the mostly recently created images:

Running the Container

Now that the image is ready to be used, run the container with the default configuration, by simply executing the command:
The container will be assigned the name ls-server (--name option) and will run in background (-d option). In addition, the exposed port 8080 inside the container will be mapped to the port 80 on local host.
To verify that Lightstreamer server is up and running inside the container, let's proceed with a double check:
  • first, run the docker ps command, which shows the list all running containers: 

  • second, open your browser to http://localhost and watch the Welcome page showing real time data flowing in from the locally deployed demo application.
Welcome page of Lightstreamer Server running inside a Docker container

Please consider that in case of a Windows and OS X systems, the Docker daemeon is running inside a Linux virtual machine, therefore you need to replace localhost with the ip address assigned to such virtual machine.

For Lightstreamer experts, another useful check is the one offered by the docker logs command, which fetches and prints on the console the standard output and error present at the time of execution:

Stopping and Removing a Container

The started ls-server container can be stopped through the command:
and finally removed with:
Remember to execute the above commands each time you want to start a container with the same name or the same mapping TCP port.

Providing a Custom Configuration

Ok, now we are sure that our Lightstreamer image has been successfully downloaded and installed, and that all checks have been passed completely, so it's time to go a step further!

For example, you may wonder if it could be possible to customize some of the multiple settings of Lightstreamer even for an server instance running inside a Docker container.
Docker allows to manage data inside and between containers, through Data Volume, which also offers the possibility to mount a directory or a single file from the host machine into a container. By leveraging this feature, a custom Lightstreamer configuration file (/path/to/my-lighstreamer_conf.xml) may be supplied as follows:
In the same way, you could provide a custom logging configuration, maybe in this case also specifying a dedicated volume to ensure both the persistence of log files and better performance of the container:
After launching the container, you might verify how the the /path/to/logs directory is getting populated with log files produced by the server.

In the following example we also updated the my-lightstreamer_log_conf.xml file, changing the factory logging path configuration from ../logs to /path/to/dest/logs, which now needs to be specified as additional host directory to mount:

Deployment of Lightstreamer Adapter Sets

To make full use of the published Official Image, let's explore how you could provide a running container with any Lightstreamer Adapter Set, either developed by yourself or provided by third parties, by employing similar strategies to those illustrated above.

Single Adapter Set

For example, the simplest way to deploy a single custom Adapter Set is to attach its deployment files into the factory adapters folder, as follows:
where /path/to/my-adapter-set is a directory on your host containing the deployment files of your custom Adapter Set.
An interesting exercise could be the deployment of our Hello World Java Adapter. Here the required steps:
  • Create a new folder /my-adapters on your host machine. 
  • Download the file from our repository project on GitHub and unzip it into /my-adapters folder.
  • Run the container with the command:
  • Verify that the Adapter Set has been successfully loaded by the server.
Upon the last command, you should see an output similar to:
which attests the correct loading of the Hello World Adapter Set.

Multiple Adapter Sets

But what if you need to plug more custom Adapter Sets onto a running container? Should you list in the command line as many host directories as the Adapter Sets to deploy? Since it might result in a tedious and error prone approach, we need better strategies.
One of them could be a fully replacement of the factory adapters folder with a one located in your host machine, in which you supply all the adapter deployment folders.
In this case, the /path/to/my-adapters folder has to be structured with the required layout for an adapters folder:

Let's see how it works in practice, extending the previous exercise with the aim to deploy the Basic Chat Java Adapter along with the the Hello World Java Adapter.
  • Download the file from our repository project on GitHub and unzip it into the same /my_adapters folder, where the deployment files related to the Hello World Adapter are already there.
  • Now the resulting layout of /my_adapters should look like:
  • Run the container with the command: 
  • Verify that the both Adapter Sets have been successfully loaded by the server, checking the output produced by the docker logs command seen before: 

Deployment of Web Server Pages

Till now we have seen how it is possible to customize the Official Image in terms of provided configuration and deployed custom Adapter Sets. But there might be some circumstances where you would like provide also custom pages for the internal web server of the Lightstreamer Server.

Even in this case, it is possible to customize the running container by leveraging the same techniques shown above.

For example, with the following command you will be able to fully replace the factory pages folder, which is the web server's root directory:
where /path/to/custom/pages is the path in your host machine containing the replacing web content files.

Building a New Image

In order to simplify the management and the deployment of containers started from the Official Image, it could be also possible to execute all the above tasks by deriving a new image, which will include all files needed for the customization.

Let's imagine, for example, that our requirement is to package up a Lightstreamer Server with specific overall and logging configurations, together with a couple of Adapter Sets. How would it be possible to accomplish such goal?

First of all, let's create a new folder which will be the base for our image:
Then, we need to populate this folder with all resources needed to build the derived image:
  • configuration files, replacing the ones embedded in the starting image, for example my-lightstreamer_conf.xml and my-lightstreamer_log_conf.xml
  • adapters deployment files, which will be attached into the default adapters folder, for example the ones belonging to the HelloWorld and Chat adapters already used in the previous examples.

The last and most important resource to add is the Dockerfile, which will instruct Docker on how to build the image:
The final resulting layout of my-lightstreamer folder will be:

Finally, we can build the image by simply running the command:
from the my-lightstreamer folder.

Pay attention on how we specified the name (my-lighstreamer) and the tag (my-version) of the image with the -t parameter, which is useful for later identification in the local repository through the already used docker images command:
All that remains now is launching the container from the newly created image.
and checking that everything is going well, with the familiar docker ps and docker logs commands:


In this blog post we dived into the just published Docker Official Image for Lightstreamer, covering a broad range of usage scenarios.

We showed you how it is possibile to customize practically every aspect of a containerized Lightstreamer Server, exploiting the features provided by the Docker platform.

We also explained how to build a new image starting from the Official one, in order to leverage the great configurability of Lightstreamer from one hand, and to maximize ease of management on the other hand, allowing you to create and handle separated server deployments, each of which focused to serve a specific environment or purpose.

Do not forget to take a look to our source repository on GitHub!

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.