Впервые о 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руб/мес
План действий для быстрого старта
- Шаг 0 - Создаем сервер ubuntu 14.04
- Шаг 1 - Устанавливаем docker
- Шаг 2 - Устанавливаем docker-compose
- Шаг 3 - Запускаем приложение
Подготовка сервера
Добавляем файла подкачки в систему если ОЗУ меньше 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
Быстрый запуск приложения
Для запуска на виртуальном сервере или локальной машине нужно выполнить следующие команды
Клонируем репозиторий
Переходим в директорию с проектом
Инициализируем и наполним базу товаров
Наполняем поисковой индекс
Запускаем наш сервис
Проверить работу нашего сервиса можно в браузере или выполнить в консоле запрос при помощи curl
Принцип докеризации приложения
Web - приложение можно разделить на следующие части:
Список сервисов для докеризации
- Rails Application - backend магазина
- Database Mysql 5.7 - База данных
- Sphinx поиск по товарам
Каждый сервис можно разложить на составляющие
- Код приложений отвечающий за бизнес логику и функционал (код приложения/mysql app/ etc)
- Данные получаемые в процессе жизненного цикла приложения
- Конфигурационные файлы приложения и его компонентов
Dockerizing mysql 5.7 database
Для докеризации базы данных мы воспользуемся официальным образом. Последняя версия mysql 5.7 Мы можем получить образ 2 путями
- Загрузить образ c docker hub
- Собрать образ на основе Dockerfile приведенный по ссылке выше
Dockerizing sphinx searchengine
Официальный образ на docker hub отсутствует на момент написания статьи. Соберем образ самостоятельно и запушим его на hub.docker.io. Примеры написание Dockerfile можно поискать на github.com. Рекомендую разобраться в работе образа mysql 5.7 и обратить внимание на файл docker-entrypoint.sh (точки входа) отвечающий за начальную инициализацию базы данных Запустить собранные образ можно командой..
или собрать самостоятельно на основе 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, нам потребуется выполнить сборку контейнера самостоятельно.
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