In this blog, We are going to explain the concepts of
Docker and integrate it with
Rails app.
Let's first understand what is Docker ?
Docker is a bit like a virtual machine. But unlike a virtual machine, rather than creating a whole virtual operating system, Docker allows applications to use the same Linux kernel as the system that they're running on and only requires applications be shipped with things not already running on the host computer. This gives a significant performance boost and reduces the size of the application.
Docker is a tool designed to make it easier to create, deploy, and run applications by using containers.
Now, You are thinking what are containers?
Operating system (OS) virtualization has grown in popularity over the last decade as a means to enable software to run predictably and well when moved from one server environment to another. Containers provide a way to run these isolated systems on a single server/host OS.
Containers sit on top of a physical server and its host OS, e.g. Linux or Windows. Each container shares the host OS kernel and, usually, the binaries and libraries, too. Shared components are read-only, with each container able to be written to through a unique mount. This makes containers exceptionally “light” – containers are only megabytes in size and take just seconds to start, versus minutes for a VM.
The benefits of containers often derive from their speed and lightweight nature; many more containers can be put onto a server than onto a traditional VM. Containers are “shareable” and can be used on a variety of public and private cloud deployments, accelerating dev and test by quickly packaging applications along with their dependencies. Additionally, containers reduce management overhead. Because they share a common operating system, only a single operating system needs care and feeding (bug fixes, patches, etc). This concept is similar to what we experience with hyper-visor hosts; fewer management points but slightly higher fault domain. Also, you cannot run a container with a guest operating system that differs from the host OS because of the shared kernel – no Windows containers sitting on a Linux-based host.
We can conclude, how Containers are differ from Virtual Machines ?
Using containers, everything required to make a piece of software run is packaged into isolated containers. Unlike VMs, containers do not bundle a full operating system - only libraries and settings required to make the software work are needed. This makes for efficient, lightweight, self-contained systems that guarantees software will always run the same, regardless of where it’s deployed.
Install Docker in you system -
Here we are going to install Docker in Ubuntu 16.10. If you have different Os please refer
Get Docker
You can download this
docker.sh script and keep it in home directory and install by running -
$ sh docker.sh
OR
You can install docker by running these command manually -
$ sudo apt-get install -y --no-install-recommends \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
$ curl -fsSL https://apt.dockerproject.org/gpg | sudo apt-key add -
apt-key fingerprint 58118E89F3A912897C070ADBF76221572C52609D
$ sudo add-apt-repository \
"deb https://apt.dockerproject.org/repo/ \
ubuntu-$(lsb_release -cs) \
main"
$ sudo apt-get update
$ sudo apt-get -y install docker-engine
$ sudo apt-get update
Verify that Docker installed correctly by running the hello-world image.
$ sudo docker run hello-world
Integrate Docker with Rails application
Go to your app directory and make a file Dockerfile. In which we install all the system dependencies packages.
In
Dockerfile
FROM ubuntu:latest
MAINTAINER Sonu Kumar <er.sonukr@gmail.com>
# Ignore APT warnings about not having a TTY
ENV DEBIAN_FRONTEND noninteractive
# Ensure UTF-8 locale
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
RUN dpkg-reconfigure locales
# Set the Ruby version of your preference
ENV RUBY_VERSION 2.3.0
# Install build dependencies
RUN apt-get update -qq && \
apt-get install -y -qq \
build-essential \
ca-certificates \
curl \
git \
libcurl4-openssl-dev \
libffi-dev \
libgdbm-dev \
libpq-dev \
libreadline6-dev \
libssl-dev \
libtool \
libxml2-dev \
libxslt-dev \
libyaml-dev \
software-properties-common \
wget \
zlib1g-dev \
mysql-client \
libmysqlclient-dev \
libsqlite3-dev \
imagemagick \
libmagickwand-dev \
nodejs \
zip
# Install ruby via ruby-build
RUN echo 'gem: --no-document --no-ri' >> /usr/local/etc/gemrc &&\
mkdir /src && cd /src && git clone https://github.com/sstephenson/ruby-build.git &&\
cd /src/ruby-build && ./install.sh &&\
cd / && rm -rf /src/ruby-build && ruby-build $RUBY_VERSION /usr/local
# Install bundler currently we're using this but we should not.
RUN gem install bundler
ENV APPLICATION_NAME=Your_app_name
# Clean up APT and temporary files when done
RUN apt-get clean -qq && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN mkdir -p /$APPLICATION_NAME
WORKDIR /$APPLICATION_NAME
ADD Gemfile /$APPLICATION_NAME/Gemfile
ADD Gemfile.lock /$APPLICATION_NAME/Gemfile.lock
RUN bundle install
ADD . /$APPLICATION_NAME
Above file prepare all the system dependencies of our application.
Now, make another file in
docker-compose.yml. These settings will download the image and will create containers. Here, I am using services for mysql and memcached. You can use different services as per your application requirements.
In
docker-compose.yml
version: '2'
services:
db:
restart: always
image: 'mysql:5.7'
environment:
MYSQL_ROOT_PASSWORD: *******
ports:
- "3306:3306"
volumes:
- "../shared/.mysql-data:/var/lib/mysql"
memcached:
restart: always
image: memcached
ports:
- "11211:11211"
web:
depends_on:
- 'db'
- 'memcached'
build: .
environment:
RAILS_ENV: development
MEMCACHED_HOST: memcached
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/your_app
ports:
- "3000:3000"
We have to configure our database.yml for using above host. So, add host as db in
database.yml
In
database.yml
development: &default
adapter: mysql2
encoding: utf8mb4
collation: utf8mb4_unicode_ci
reconnect: true
database: docker_development
pool: 15
reaping_frequency: 25
username: root
password: ********
host: db
port: 3306
Now, we have to build docker services
$ sudo docker-compose build
Up the docker infrastructure by running. It will run you rails server also
$ sudo docker-compose up
You can run all rake commands by preceding docker-compose exec web
ex-
docker-compose exec web rake db:create
docker-compose exec web rails c
docker-compose exec web mysql -u root -p
docker-compose exec web tail -f log/*.log