There has been much hype in the Dev/DevOps community in the past few years about Docker and sometimes used interchangeably with containers. Almost every Platform As a Service provider out there brags about their technology supporting the latest releases of Docker. Sometimes you wonder whether adopting these new technologies is worth the risk after all. As Donald Knuth says "Every one should focus on doing good science and not popular science". Is Docker and container technologies only hype? or is there more to learn and take advantage of in this niche developer ecosystem.
What is Docker?
If you've never heard of Docker don't worry. We can't talk of Docker without having an idea of what a container is. A container is an application and all it's dependencies packaged to share the kernel and runs as an isolated process in the user space on the host operating system. Docker containers are a specification of containers that runs on all major Linux distros, Mac OS, Microsoft Windows and on any infrastructure. Docker containers wrap a piece of software as a complete filesystem including code, runtime, system tools and libraries which can be installed on any computer infrastructure and guarantees the software will run the same regardless of the platform.
Docker containers are extremely lightweight whereby, running containers share the same OS kernel which uses less RAM. This is based of a Docker image which is constructed from a layered filesystem which shares common files making disk usage much more efficient. This capabilities alone accelerate developers by eliminating environment inconsistencies and provide more room for engineering creativity.
Why Dockerize your Rails Application
It's hard to develop a Rails application without adding specifications for your respective platforms in the gem file. Developing Rails applications removes these environmental inconsistencies by packaging the application together with the configuration and dependencies so it can work consistently on any environment in test or production mode.
This removes a lot of weight from the developers' head by enabling them to use the best tools for application services and not worry about tooling conflicts.
Installing docker will vary slightly depending on your platform. But if you're a Linux user, the steps are straightforward as outlined on the documentation. Once you have installed the Docker Engine or Docker Machine create a new environment based on Virtualbox and configure your computer to use that environment for docker. This can be verified by running the hello-world image.
$ docker run alpine:3.3 echo Hello world!
Create your first Docker image for your Rails App
It is highly recommended you go through the Docker documentation to have a clear understanding of the docker engine. Docker applications are configured using a Dockerfile which defines how a container should be built.
There are not that many keywords that we must understand in-order to produce a
Dockerfile. The most important of them all is
FROM, quickly followed by
RUN. It's extremely rare that you won't need
RUN, though entirely possible. To configure a basic Dockerfile for a Rails application,
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /railsapp
ADD Gemfile /railsapp/Gemfile
ADD Gemfile.lock /railsapp/Gemfile.lock
RUN bundle install
ADD . /railsapp
This simple docker file puts your application inside a Docker image which will build a container with ruby and bundle all application dependencies with it.
Next, we'll need to create a bootstrap
Gemfile which just loads Rails; then empty the gemfile.lock to build to Dockerfile.
gem 'rails', '22.214.171.124'
Deploy and Enjoy!
To run our Rails application we will need a Docker Compose yml, build the Dockerfile and deploy. the docker-compose yml describes the services comprising the rails application. It describes the docker images needed to run the application successfully and also configures them together exporting the web application port. For example
version: '2' services: db: image: postgres web: build: . command: bundle exec rails s -p 9000 -b '0.0.0.0' volumes: - .:/railsapp ports: - "9000:9000" depends_on: - db
Then application is then deployed as shown below
docker-compose run web railsapp new . --force --database=postgresql --skip-bundle
The steps above builds a docker image for our web service and runs our rails app inside a container on our computer. You could check out the docker documentation for further information.
Moving from our conventional DevOps systems to Docker is hard but the hard work pays off in the end. This creates an environment for your development team to be more productive and creative.