Sunday, June 19, 2016

Introducing Bitnami Development Containers

Folks who have known me for a while, know that I love to make things easy for developers. From my days as a usability engineer on the Visual Studio team, to my pet projects, to my tutorials and samples, making programming easy and fun has been a theme of my work since 1998.

Now at Bitnami, I am happy to be working with a team who is as excited about this as I am. We have started a project that takes advantage of Docker to make developing with whatever framework you choose easy and fun. We call this project “Bitnami Development Containers.” This project is an extension of the development process that we have created for our own internal development. It only made sense to share our experience with developers everywhere.

We are in the beginning phase of the public part this project, and we are practicing the “release early and often” strategy, so let’s see what people think.

The basic idea behind the project is that if you have Docker enabled on your development machine, trying a framework should be as simple as what I affectionately call, “curling up”. That means that all you need to do is curl (download) a docker-compose file, and then run it with the docker-compose up command. After those two steps, and only those two steps, you can see your app running and start coding. It is that easy.

To accomplish this, we had to do a couple of things:
  1. First, we created custom containers that are meant specifically for developing with the frameworks of interest. These containers have an entry point that is designed to get developers going with zero configuration. We take care of all the configuration and any code generation necessary to get started.
  2. We include any necessary infrastructure and orchestrate them together using a simple docker-compose file. That means that if your framework of choice requires a database, maybe a specific database configured in a specific way, you don’t have to worry. We took care of all the work to set it up that way. You can just start coding.
So, for any framework that we support, with a development container, for example, if I wanted to write some good old Ruby on Rails code, I would just do this:

$ mkdir myrailsapp
$ cd myrailsapp
$ curl -L "" > docker-compose.yml
$ docker-compose up

Then open my browser, go to my docker-machine’s ip address at port 3000. And there’s the Rails welcome page. 

The exact same process works for Express:

$ mkdir express
$ cd express
$ curl -L "" > docker-compose.yml
$ docker-compose up

Then open my browser, go to my docker-machine’s ip address at port 3000. And there’s the Express welcome page. It’s always the same simple steps.

One important thing to note is that the containers are designed to work as immutable infrastructure. By that, I mean, none of the code that is generated or that you write is on the container. Rather, it is also mounted in a volume. That is important because it means that the containers support easy reproducibility. So, if you change some code, you can check in that code, and someone else can check it out, and docker-compose up just works with the existing code.

Ok, let’s just try it. I heard about Laravel. My team says it's pretty cool, but I never really knew what it was. So, I am going to using Bitnami’s Development Container to quickly get started with it.

First thing, I will create a directory for the application that I will write. Then I will download the docker-compose file into that dir. Again, the same simple steps, “curl up.”

$ mkdir laravel
$ cd laravel
$ curl -L "" > docker-compose.yml

That went fast, so let’s take a look:

$ cat docker-compose.yml

Ok, that is a nice and simple file. I can see that I am going to get a copy of MariaDB along with it. That’s handy, since as far as I can tell, Laravel and MariaDB go together like peanut butter and jelly. Note also that the port is already mapped for me.

Finally, note that it mounts a volume called “./app”. This is very important and interesting. What this means is that the application code that is generated and that I will modify is NOT in the container, but rather right on my desktop. This is how we achieve the immutability I mentioned above. This way, besides being easy to manage with source control, it is also trivially easy to edit with my desktop editor.

So, I curled, now I up. Of course, make sure that Docker is running before you do this:

$ docker-compose up

The first time I run this, Docker will download the images first. Then it will start the containers.

Looks like the container is started. Let’s check out the app.

First, I’ll check the ip address of my Docker VM:

$ docker-machine ip

Now that I have that, I can navigate to port 3000. Port 3000 is a typical port for development web servers to run on. I could also tell I needed to port 3000 from the docker-compose file.

It works! Let’s pause for a moment and consider how cool this is. In a matter of minutes I went from having an empty Docker environment to having a running Laravel 5 app. And I’ve never used Laravel before.

Of course, the first thing I want to do is to change the default to prove to myself that I have some control over the content.

Because this is my first experience with Laravel and I know almost nothing about it, I will have to poke around a bit. I’ll just guess that the string displayed in the default web page will help me out, so I will start with a recursive grep.

$ grep "Laravel 5" -R ./

That “welcome.blade.php” file looks like a promising start for making my first change. Keep in mind, I have never even written PHP code, much less Lavarel code. But, I love to learn by doing, so I am just going to dive in with my editor and see if I can make a change.

And …

Yup! It’s that easy. Within minutes, I have made a change!

Let’s take another look at my Mac’s directory:

As I mentioned before, you can see that the application code is on my development machine, NOT in the container. Furthermore, the docker-compose.yml file that sets up the development environment is in the same directory. That means I can easily commit this directory and share it. Anyone could check it out from source control, and run $ docker-compose up, and end up with the exact same environment. So, a team of developers could easily use the Bitnami Development Containers to collaborate on projects, and easily stay in sync with both the development environment and the code.

Today we have 3 development frameworks ready. Rails, Express, and Laravel, with more on the way. Please try them out and give us feedback. And please let us know what other frameworks you think we should do next! You can reach us at

- Rick Spencer, Bitnami VP of Engineering