Docker и настройка development окружения в контейнерах интернет магазин - Dockerizing eCommerce Ruby on Rails Application

Впервые о docker я услышал в 2014 году на конференции YAC от Яндекса. На тот момент это был молодой продукт с массой нерешенных проблем. С тех пор докер активно развивается и набирает популярность. Появляются инструменты позволяющие использовать docker проще и эффективней.

Примеры по запуску web приложений в официальной документации являются простыми и не дают все картины плюсов и минусов по использованию docker. Это первая статья из серии где мы займемся подготовкой development окружения для работы над проектом. По окончанию работы мы получим связки из Rails On Ruby приложения использующею mysql-5.7 для базы данных и sphinx 2.2.1 для поиска. В проект будут загружены данных около 80 000 позиций товаров реального интернет магазина

Одна из задач данной статьи - это повторяемость проводимых экспериментов. Статья была протестирована на Облачном хостинге с почасовой оплатой от simplecloud. Достаточно тарифа 1Gb ОЗУ/1 ядро/20Gb ssd (0.4р/ч) или 250руб/мес

План действий для быстрого старта

Подготовка сервера


Добавляем файла подкачки в систему если ОЗУ меньше 3GB
dd if=/dev/zero of=/swapfile bs=256M count=8
chown root:root /swapfile
chmod 0600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile  none  swap  sw  0  0" >> /etc/fstab

Команды для быстрой установки docker и docker-compose на машину под управлением ubuntu 14.04
apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
echo 'deb https://apt.dockerproject.org/repo ubuntu-trusty main' > /etc/apt/sources.list.d/docker.list 
apt-get update 
apt-get install linux-image-extra-$(uname -r)
apt-get install docker-engine vim git -y
curl -L "https://github.com/docker/compose/releases/download/1.8.1/docker-compose-$(uname -s)-$(uname -m)" > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

Быстрый запуск приложения

Для запуска на виртуальном сервере или локальной машине нужно выполнить следующие команды
Клонируем репозиторий

git clone https://github.com/asigatchov/docker_demo_shop.git /home/docker_demo_shop

Переходим в директорию с проектом
cd /home/docker_demo_shop

Инициализируем и наполним базу товаров
docker-compose run shop.service.dev rake db:create db:migrate update_db_shop:import

Наполняем поисковой индекс
docker-compose run sphinx sh -c 'sleep 10 && indexer --all'

Запускаем наш сервис
docker-compose up

Проверить работу нашего сервиса можно в браузере или выполнить в консоле запрос при помощи curl
curl 'http://SERVIR_IP:3000/'

Принцип докеризации приложения


Web - приложение можно разделить на следующие части:

Список сервисов для докеризации

  • Rails Application - backend магазина
  • Database Mysql 5.7 - База данных
  • Sphinx поиск по товарам
Схема docker компонентов в RoR приложение

Каждый сервис можно разложить на составляющие

  • Код приложений отвечающий за бизнес логику и функционал (код приложения/mysql app/ etc)
  • Данные получаемые в процессе жизненного цикла приложения
  • Конфигурационные файлы приложения и его компонентов
docker and rails on ruby application

Dockerizing mysql 5.7 database


Для докеризации базы данных мы воспользуемся официальным образом. Последняя версия mysql 5.7 Мы можем получить образ 2 путями
  1. Загрузить образ c docker hub
  2. Собрать образ на основе Dockerfile приведенный по ссылке выше

Dockerizing sphinx searchengine


Официальный образ на docker hub отсутствует на момент написания статьи. Соберем образ самостоятельно и запушим его на hub.docker.io. Примеры написание Dockerfile можно поискать на github.com. Рекомендую разобраться в работе образа mysql 5.7 и обратить внимание на файл docker-entrypoint.sh (точки входа) отвечающий за начальную инициализацию базы данных Запустить собранные образ можно командой..
docker pull asigatchov/sphinx

или собрать самостоятельно на основе Dockerfile

 
FROM ubuntu:14.04

RUN groupadd -r sphinx  && useradd -r -g sphinx sphinx

# add gosu for easy step-down from root
ENV GOSU_VERSION 1.9

RUN set -x \
  && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget libmysqlclient18  unixodbc libpq5  && rm -rf /var/lib/apt/lists/* \
  && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
  && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
  && export GNUPGHOME="$(mktemp -d)" \
  && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
  && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
  && rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \
  && chmod +x /usr/local/bin/gosu \
  && gosu nobody true \
  && wget -O /tmp/sphinxsearch.deb http://sphinxsearch.com/files/sphinxsearch_2.2.11-release-1~trusty_amd64.deb \
  && dpkg -i /tmp/sphinxsearch.deb \
  && apt-get purge -y --auto-remove ca-certificates wget \
  && mkdir -p /var/lib/sphinxsearch/data \
  && mkdir -p /var/log/sphinxsearch \
  && mkdir -p /var/run/sphinxsearch

EXPOSE 9312 9306
ADD entrypoint.sh /usr/local/bin/
CMD ["entrypoint.sh"]

Dockerizing Ruby On Rails Application


Для построения контейнера мы воспользуемся официальным образом phusion/passenger-ruby22. Так как образы статически а состав библиотек приложения описывается в Gemfile, нам потребуется выполнить сборку контейнера самостоятельно.
Любые изменения в Gemfile требуют запуск сборки контейнера

 
FROM phusion/passenger-ruby22
RUN apt-get update \
  && apt-get install  -y \
  build-essential \
  nodejs libxml2 \
  && apt-get upgrade -y -o Dpkg::Options::="--force-confold" \
  && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
  && gem update bundler \
  && gem cleanup \
  && locale-gen ru_RU \
  && locale-gen ru_RU.UTF-8 \
  && localedef  -i ru_RU -f UTF-8 ru_RU.UTF-8

ENV LANG ru_RU.utf8

RUN mkdir -p /app
WORKDIR /app

COPY Gemfile Gemfile.lock ./
RUN gem install bundler && bundle install --jobs 20 --retry 5
COPY . ./
RUN rm -rf /app/public/assets/* && rake assets:precompile

EXPOSE 3000

CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "-p", "3000"]

Создаем docker-comose.yml для связи компонентов

Для связи контейнеров есть отличный инструмент docker-compose (ранее fig). На момент написание данной заметки актуальная версия формата 2.
version: '2'
services:
  db.shop:
    image: mysql:5.7.14
    volumes:
      - ./data/mysql:/var/lib/mysql
      - ./shop/config/my.cnf:/etc/mysql/my.cnf
    environment:
      SERVICE_NAME: db.shop
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: my_shop_ru
      MYSQL_USER: myshop
      MYSQL_PASSWORD: shopmyru
    ports:
      - '3306'

  shop.service.dev:
    build: ./shop/
    environment:
      SERVICE_NAME: shop
      DB_HOST: db.shop
      DB_NAME: my_shop_ru
      DB_USER: myshop
      DB_PASS: shopmyru
    volumes:
      - ./shop/:/app
    ports:
      - '3000:3000'
    depends_on:
      - db.shop
  sphinx:
    image: asigatchov/sphinx:2.2.11
    depends_on:
      - db.shop
    volumes:
      - ./data/sphinx/data:/app/db/sphinx/development
      - ./data/sphinx/log:/app/log/
      - ./data/sphinx/binlog:/app/tmp/binlog/
      - ./data/sphinx/tmp:/app/tmp/
      - ./data/sphinx/tmp/binlog:/app/tmp/binlog/development
      - ./shop/config/development.sphinx.conf:/etc/sphinxsearch/sphinx.conf

Вам может понравиться