Why do we recommend Docker?

This article aims to explain why the project recommends running Xibo inside Docker containers, and the underlying reasons for that decision. It is in places necessarily technical in nature, but I have tried to explain the concepts where possible to make this accessible to everyone.

Since the 1.8.0-rc1 release of Xibo, we've been strongly suggesting users transition away from "custom" installs of the CMS (where everyone rolls their own environment to host the Xibo CMS) over to one based upon Docker containers.

Where we accept we've done a poor job, is explaining why the project has taken that approach, and indeed the benefits to you as a user of adopting a container-based solution.

Docker has become increasingly popular over the past few years as it allows software developers to package an application along with the required environment for it to run, in a reproducible way. This ensures that the environment you're running your Xibo CMS in is exactly the same environment as it is developed in, and is tested in.

To be absolutely clear from the outset, the use of Docker is a recommendation and not a requirement.

The Journey

There were several key development goals for the 1.8 series. Firstly we wanted to move the CMS over to use a recognised PHP framework. If you're not a developer, then a framework is simply a structure which allows you to build an application. There are many advantages to that, but key amongst them from our view point was to enforce a layered security approach, improve the end users ability to add custom code to the CMS without modifying the core, and so that new developers coming to the project could understand the layout of the application - since it follows a standard structure.

We decided on the Slim framework, as it met the needs we had, and our team had experience with it.

Secondly, we wanted to get our use of third party libraries under control. We opted to use Composer. Composer allows us to express all the libraries Xibo uses in code, and then manages downloading and versioning of those libraries.

Libraries are reusable blocks of code that perform a specific task. In a trivial example, one might for example take text in, and output the same text but in upper case. They allow developers to benefit from the combined expertise and experience of many others, so that the same issues aren't encountered again and again by every project developing their own solutions to the same problem.

Library code however isn't generally designed to be directly run. Often there are files that are distributed with a library that form its test suite, or examples of how to use the library. Traditionally, all the files a library ships are distributed along with the main application, which means all those undesirable files are installed on to your webserver along with the application. As a result of that, someone may come along and run those files using your webserver (simply by knowing or guessing where they are). If you're unlucky, one of those files might be badly written and expose information about your server which you would prefer wasn't accessible. Worse still, it could be exploitable allowing an attacker to take control of your server.

What Xibo (and many other projects now) does is move all of that library code where it can't be directly accessed. If you look at the file structure of a Xibo CMS installation (outside of Docker), you'll see a folder with lots of other folders inside it, one of which is called web. It's only the web directory that your server should expose to your users.

That vastly reduces the potential attack surface the CMS adds to your server, by not making all of that library code directly accessible.

cms-structure

Third on the list of requirements, and something we really wanted to bring to the software, was the ability for the CMS to communicate with the Player in real time (push messaging). In Xibo, this is called XMR.

XMR opens up some really exciting possibilities. In its simplest form, it allows Players to pickup changes to scheduled content, or schedules in near-real-time. Leveraging that ability, a world of event-driven signage is opened up where content on screens can react to events around them. So for example, a building fire alarm, via an integration and the Xibo API could trigger screens to show a warning, and the nearest exit route for visitors to leave the building safely.

XMR, built with the ZeroMQ protocol, requires its own server process to be running. Unfortunately that can't be done via a webserver as requests to a webserver time out after a period of time.

XMR is optional, in that the Players will be able to function without it, however you loose the ability to send near-real-time updates to the Players, reverting instead to periodic polling.

There were many other goals in the 1.8 development cycle, but those are the ones that impact directly on the topic of this article.

So with those constraints in mind, we now have the following requirements:

  • CMS file structure where only the web directory should be served by the webserver
  • Long-running XMR process required for push messaging to work

Those requirements are unfortunately at odds with a typical shared hosting environment, where you are unable to adjust the webserver configuration to make public only a small portion of your allocated space. Similarly, those kinds of environments typically won't allow you to run additional long-running server processes.

What we therefore wanted to do was offer our users a credible framework for deploying the new style of CMS, in which as much of the complex setup as possible was abstracted away.

Docker has fast become the industry choice for containerised deployment of applications. It offers both the simplicity we wanted, as well as the flexibility for more experienced users to customise their deployments to meet specific needs.

XMR requires the ZeroMQ libraries and support in PHP for that, which is not commonly found in most PHP environments. Docker allows us to abstract that setup and ensure that the versions of those libraries we're working with are the optimal ones for our needs.

As the CMS continues to develop, it's likely that Xibo will require more in the way of supporting services to better manage things such as timeseries data (eg proof of play statistics, logs) - which currently live in the database, but probably shouldn't. As those supporting services and libraries increase in number and complexity, manually meeting those requirements will become more and more work.

Initial setup of the CMS aside, there are other benefits - such as easy portability of a CMS between servers, easier upgrades (and rollback should an upgrade fail).

It seemed natural therefore for the project to build and maintain Docker containers for the CMS, offering those without the expertise to setup and manage their own environment to meet Xibo's needs with a viable and supportable means of getting the CMS installed and working.

That could be on local hardware, or on many of the low-cost VPS providers that are becoming ubiquitous.

Some important benefits from the project's side have been realised as a result too. We've seen a step-change in the issues reported to us. It's now rare for us to receive an issue report where the problem isn't easily reproduced locally. That's meant that the bugs we have logged for 1.8 series are, in the main, actual issues with the software which we've been able to identify and resolve, rather than vague issues which come and go based on exact versions of libraries being used. We believe that has already paid dividends in the quality of the CMS application.

I hope that I've been able to explain to you, our users, the reasons behind our push for Docker. If you choose to run with Docker, or at least give it a fair trial, then my thanks go out to you. If you choose to run on your own Custom setup then my thanks go to you too for using and supporting the project. You are all awesome!