Here at Ardoq we are big fans of Docker and we have recently invested more time into optimizing our Docker stack. After doing so, we decided that we should take the time and share our experiences thus far.
We use Docker as the foundation for our add-on architecture, as well as packaging and distribution model for our on-site installations.
Docker allows for easy maintenance and update of remote applications. We simply grant access to our Docker Hub Repository, where we store both public and private images, send a docker-compose.yml file to the customer. The docker-compose file specifies all versions of the images, and how they are interconnected. When the customer wishes to update, it’s simply a matter of getting a new docker-compose file and restarting the stack.
The requirements for an on-site installation is simply: one large server that supports Docker.
We use about 15 different Docker containers to compose our app, and this number is growing, so we need to keep the size of the images as small as possible.
For our database containers, we use the official Docker distributions of MongoDB and Redis just to be sure that we have a solid back end. Both are based on Debian Wheezy.
All other Ardoq Docker images are based on Alpine Linux, a distribution similar to Busybox. The advantages of using a minimal base image are many – download speed and hard disk space really becomes noticeable when you work with many images and frequent releases!
Security is a not so obvious, but even more important effect. A minimal image has fewer components that can be exploited. For instance, none of our servers have ssh enabled.
The Ardoq API is implemented using Clojure, which we prefer to run on Oracle’s JVM. Until recently it was difficult to get this running on Alpine, but this now works like a charm. We have followed this example which only uses 175.1 MB compared to 480.8 MB for the official release.
Our smallest image is the Logstash forwarder – 14 MB. It only contains the forwarder binary on top of Alpine. In theory we could also skip Alpine, but it is convenient to have the ability to enter the container for debugging purposes.
Another benefit of using Docker is that we get to isolate setup that is specific to each service. For example, our .Net add-on that allows us to automatically analyze .dll files using Refit and Mono, and a simple Node server. With Docker this add-on can run next to any other add-on without us having to worry about library conflicts.
In conclusion – we at Ardoq have embraced Docker as a powerful and flexible tool to develop, test, package and distribute a broad variety of applications.
Finally – some best practises:
- Build your images from the smallest possible base image
- Re-use your base containers – to reduce transfer time
- For persistent data, use data only containers – to replace containers without losing data.
- More useful tips here: Best practises for writing Docker files
In the coming weeks we will follow up with more details into the “how” of our Docker implementation. Next week we will explain how we backup our customer data from our Docker stack, also using Docker.
Other blog posts related to Docker