Praise the whale carrying containers (that is their logo, or probably it’s a dolphin, or maybe a whale). Anyway, here it is, decide for yourself, I propose a poll.

Docker Containers for Easier App Deployment

I actually wanted to write something about Perl, but then I realized that in the last few months I worked with this incredible tool and also that it is not very popular in our company, or maybe in our department, or probably in our company, I propose a poll for that too.  AND IT SHOULD BE POPULAR, EVEN TANTI MARIA SHOULD KNOW ABOUT IT!!!

I don’t know how many of you have heard about it, but I encountered it about 2 years ago and I wanted to implement it on an ongoing project. I think it was version 1.2 or maybe 1.3 or perhaps… you can see where this is going. It seemed a pain in the ass, a bunch of CONFIG files, with a lot of BASH, not very cool documentation, it didn’t work on Windows very well (not that I use it), images and containers and.. What the container in the image is going on??

So, I dropped it, and I continued with the old approach. The truth was that I was too lazy, but like any other tool or language, you have to take it from the beginning, and study it. Eventually, that’s what I did, and I discovered a huge technological entity which can help you automate your work, their motto being “BUILD, SHIP, RUN”.

What is Docker?

It’s a docking tool, dooh. It’s a tool that helps you automate the deployment of applications on any environment you want.

It is based on containers.

As the definition on their site states: ”these containers wrap a piece of software in a complete filesystem that contain everything needed to run: code, runtime, system tools, system libraries – anything that can be installed on a server. This guarantees that the software will always run the same, regardless of its environment.”

Docker images?

These are files, formed of many layers – these layers usually represent other images – which incorporate a minimum number of features of an operating system – a distribution of Linux.

Where do we get these images?

We have https://hub.docker.com/. Here you can find a ton of images Perl, Node, Python, Ruby, Nginx, Redis, MySQL, Mongo etc – kinda’ anything you need. Or you can build them yourself starting from a base image like ‘debian’ or ‘centos’ and upload them on docker hub. More on how to later.

What do we do after we get these images?

You start containers from those images. For example, if you have a Nginx or Apache image and you start a container using that image then on that container, you will have a running instance of Nginx or Apache.

Is Docker a VM?

Well, no, not quite, maybe, could be, mneah. It uses the host resources and the containers run on the same operating system as the host. So, if you have a 1GB VM and you want 6 VM instances it will cost you 6GB, but if you have a 1GB docker iamge you can start 6 containers from that single image => 1GB cost. A note here: on Windows and Mac it uses VirtualBox to create the docker daemon and emulate the whole docker environment.

So don’t think of it as a VM, think of it as an AA meeting group where Node and Redis and Nginx and Perl and MySQL get together as totally different people (containers) and work something out together.

 perl2

 

How do I configure it?

You use Dockerfiles. From these files you form images, in which you can install pretty much anything you need. For example, if you have a Node base image – you can start from that, you can find it on dockerhub with the latest version of node – in the Dockerfile you can add custom packages like bluebird or request or imagemagick or whatever package that does not come by default.

You can add custom linux packages, add custom files, run certain scripts etc. More here https://docs.docker.com/engine/reference/builder/

Once you finish with the Dockerfile you can build your image using ‘docker build’ command. Once you have the image you can run a container or two, or three or maybe one from that image using ‘docker run’ command. Of course, these commands are not that easy, you can configure the container/image name, which ports to expose, port forwarding, ip forwarding, network management – !! Docker networking is an awesome feature; you can build networks inside your containers and link them according to your needs.

Do I have to do all of this from the command line?

Of course not! You have docker-compose which uses .yml files, kinda like JSON only, you know, yml. This huge reference will help you configure your whole project using compose. Compose is the shit! It is used to fire up the containers from uploaded images or from current builds.

How do I link my app to these containers?

Docker together with compose have this great feature which is ‘data volumes’. You can mount whatever you want to wherever you want on the given container.

Can I connect to these containers?

Yes. Use ‘docker exec’. You can run any command which is available on a container from the command line like so: docker exec  container_name mysql –uroot –p123 database –e’select * from user’ – this means that you have MySQL installed inside the container and you can run that command.

Did you finally use it?

Yes, finally!! On Calendis. The development has been fully moved to Docker, that means: 2 Perl Instances + MySQL + Redis + Nginx => 5 containers. Of course in the beginning of the migration I found out a lot of stuff that I did not take into consideration and needed fixing. But now we run a stable Docker environment.

The environment was based on a VM, which was passed around to whoever came into the team. It was a bit time consuming. Now we can install the whole environment on a new system in … if there is an SSD about 30 min, without SSD 45min. Aaand it works on Windows as well!! 

Tips and tricks

On a Windows host before you git clone your projects use this command to solve the line endings (Windows vs Linux) issue:

git config –global core.autocrlf input

Verify if you have an errored container which has ‘restart’ set to ‘always’ and you plan to forget about it. It will consume a shit load of memory.

On Mac, if you plan to build a MySQL image, in the Dockerfile set mysql user id different from 1:

RUN usermod -u 1000 mysql

More on http://stackoverflow.com/.

perl 1

 

 

Article written by Tudor Crisan