Today we will show you how to do this with Docker and what are the first steps to “dockerize” a Ruby application.

What is Docker

Docker is a tool that allows developers to specify which is the operating system configuration that will run the application. Docker provides an abstraction layer for configurations of this virtual environment called the container. What makes docker to be adopted on a large scale is that it allows you to package all the dependencies of a stack into a single container unit.

Docker installation

See the official installation manuals for your operating system.

But basically you can run on Linux:

Or on OSX:brew install docker

Multiple environments with Docker

In real life working with projects, you need to organize images to work with various environments. For example, in a production image, you do not need to have your text editor set up.

In an image that just runs your test suite, you do not need to have the same tunning configuration of the database.

Images

The images are for you to have a bootstrap of your application. So if you want to upload an image with Ubuntu you can create a Dockerfile with the following content:

Wow! With just one FROM <system-operating-image>, you can already start a machine with Ubuntu.

To dock an app, that is, port to the world of containers, we need to define which operating system and which tools we install. There are some official images that already guarantee the basic set of tools for each stack. So it’s worth extending these images and adapting to your need. In this example below, we’ll use the official image that contains the ruby.

The images can also be versioned, and each version gets split with <image:version>, so it could be FROM ruby:2.2.4to specifically download the 2.2.4 version.

In Dockerfile you have specified the image you want to use and a command you want to execute within the image.

This way, we now need to download the image and build locally with docker build.

Docker build

To build the image above, you must use the docker building, the folder where the Dockerfile is.

When running locally, you will have an output like this:

Now if you try to run again, you will see that the image in the output has already been cached.

Note that it has not rotated the Ruby command because this part is already cached.

But what happened in practice? Let’s inspect the images.

Docker images

Use the command docker images to check which images are available on your computer:

725 MB? To make a simple hello worldCry

The official ruby image is based on UBUNTU and so it’s pretty big.

There is a version based on Alpine Linux , which is a more compact version of linux.

So let’s change the Dockerfile to use the alpine.

And we will update the image again by running one $ ruby docker build..

And now by checking the size of the image:

Much better with 125.3 MB.

Cool, now we have a space to work with ruby inside a container. Just synchronize the project into the container. And there are some ways to do this:

Copying resources

Doing the build, copying the application files to the image is useful when you want to do the self-contained deploy of the application. Changes to these files will need to be committed to the container, which makes development more difficult, but to deploy in production environments is the best way to work.

Through volumes

Mapping volumes into containers are useful when you want to change the container’s files without having to rebuild the image. Ideal for development environments, where you change a file and have the need to test the changes in time.

Linking Features

Linking features are useful for making containers more compact. Ideal for organizing and keeping containers simple but sharing information with each other.

Docker run

The docker command buildgenerated an image of a container with Ruby installed.

This allows you to reuse this image. Extend the image by adding more functionality or configuring it to the project specifications.

You can also run a command directly from within the container.

Nice! I’m running ruby without having to install anything locally!

Build Options

In the build process, it is possible to create a repository/ tag in the image with the option -t <repo/tag>. This can be useful for re-taking pictures in the future. Example:

Checking the image with docker images:

The image now appears with REPOSITORY and will make it easier to reuse in other containers.

To run the server with the image type:

Where it -pserves to bridge the gap between <door of container>:<local door>.

Trying to access locally via localhost: 4567 will not be available because the bind was made to 127.0.0.1 while the docker waits for the host 0.0.0.0.

That way we will have to change the server sinatra to bind in the correct host:

Registry

The docker registry is the official platform provided by the docker staff itself for you to keep the docker images and share images.

Docker push

With the docker push command, you can share your updated image in an image repository or in the Docker Hub. Afterward, it is not necessary to run docker build recompiling everything. So just make one docker pull to download the finished image.

Docker pull

The docker pull command is used to download the ready-made images from the repository.

Each image is made up of multiple layers and you can download and synchronize only the fragments of the image.

Docker compose

You should now be thinking of installing your entire toolbox into a container and not messing up your machine by spreading random libraries wherever you go.

But slow! Take a look at the docker compose that he serves exactly for this! It helps you compose container units and work with a subset of containers that talk to each other.

Already in the process of using in production, it is also worth seeing:

Kubernetes and docker swarm for orchestration of containers

Apache mesos and [open shift] for PAAS

A little more!

And you’re using docker in your day to day life? Be sure to share your experience in the comments!