I had an idea to experiment with Travis CI recipes and Docker (a really promising technology I wanted to learn) in order to get Travis CI tests executed locally. My intention was to simplify the way I can debug Codeception test. If a test fails, and Travis CI goes red, I had no way to enter the environment of failed build, and do a debug. I had to guess what could go wrong, then fix it locally, push, and cross fingers waiting for tests to get passed. As Codeception tests run for about 20 minutes, fixing a bug this way could take a while. My second idea for RoboCI was to provide a virtualized environment for Continuous Integration services, that could be executed on any host. Actually, with RoboCI you can run Travis CI tests on your Jenkins or Bamboo server.

What makes Travis CI cool? Travis is not just a free continuous integration service, used by most of open-source GitHub projects. What actually makes Travis awesome is the way it builds powerful virtualized environments with a very simple configuration. Travis CI by default installs everything needed for testing purposes: PHP, MySQL, Xvfb, PhantomJS, and other tools. This is done using Travis Cookbooks, provisioned by Chef. By the way, you can easily recreate Travis testing environment using Vagrant, but I was very stubborn and used Docker instead.

Why Docker? Docker creates and manages lightweight Linux containers. It does not create a virtual machine, but isolates processes and filesystem of containers. It is done using standard Linux kernel mechanisms, thus, it does not decrease a performance. For instance, you can push your web application into container, copy this container to site, and run a container on hosting. This makes Docker a really awesome tool for deployment. Finally you can just copy contents and environment from your local machine to server, and be sure, that everything will be executed practically in the same way. If you didn't use Docker for deployment, you should try!

I planned to use Docker for Travis CI tests, because I wanted a lightweight solution, with no virtualization. Also I was planning to allow integration with current Continuous Integration services like Jenkins. Nobody will run VirtualBox on hosting for testing purposes only. Lightweight containers that will run your applications in different environments will fit much better for this case.

Right now I need to say I'm really happy with my solution. At start, I thought I will have just a Travis CI runner implemented in PHP. I ended with my own custom virtualized environment runner, which can be customized to run Travis CI and custom builds as well. Because of the different approach to virtualization, Docker containers can't be provisioned in a way it is done for OpenVZ (which is used by Travis CI). For instance, the most important limitation of Docker is a rule one process for one container. This rule is really handy when it comes for CI builds. We don't need container to be run longer then tests inside it. Also we need container to be rebuilt every time we execute tests. This is what Docker is really good for and I need to say a way better then heavy but powerful virtual machine. You can enter container just by running

docker run -i -t my_container bash

without using ssh. The same way we could execute tests without entering container:

docker run -i -t my_container codecept run

But back to the Docker main limitation, we could do that for a very basic testing environment. Database engines like MySQL, PostgreSQL, or MongoDB, are not expected to be executed in the same container as our build. Unlike virtual machine, Docker does not start any process manager, like Upstart, inside a container. The only command it expects to be executed is codecept run. Thus, no one could launch MySQL or Mongo before our first process.

That's where RoboCI architecture differs from Travis CI. I decided not to use Travis CI cookbooks for provisioning database engines. I use prepared Docker containers instead. Docker has a registry of images, which could be used to get database engine, and make it run inside container.

RoboCI is a plugin for Robo Task Runner. It parses .travis.yml configuration, prepares Docker containers, and launches it for build. Docker is very smart to cache all installation instructions and launch virtualized environment really fast. From what I've seen my Selenium tests executed inside container runs much faster then on my local machine. This happens, because of virtual framebuffer - xvfb - used inside container.

RoboCI is still an experiment. It is advanced tool, and it may require customization for your projects. But if you are PHP developer and you want to have power of Travis CI on your local or remote machine this is what you are seeking for. Follow the installation instructions. You will need nothing more then standard .travis.yml config to start.