Статьи

Счастливый конец: эпическая сага о страже и докере

dockerguard

Мне никогда не нравилось, как проекты загрязняют мою систему. Библиотеки, базы данных, очереди сообщений, вы называете это, и мне пришлось установить его. В этой общей вселенной миры сталкиваются только с вопросом времени. Два проекта требуют отдельного Redis, и я застрял как решатель человеческих зависимостей.

В прошлом были попытки создания силосов. Ни один из них не был столь могущественным или столь же многообещающим, как Докер . Несмотря на это, это не без грубых краев. Это история об одном из этих краев.

У меня есть проект Rails с существующими тестами, которые я хочу Dockerize. Чего у меня нет, так это хорошего способа получить обратную связь, когда я занимаюсь рефакторингом. Я хочу запустить гвардию, чтобы я мог сделать TDD Обычно запуск Guard не имеет большого значения, но Docker (по крайней мере, на Mac) делает это проблемой (это связано с libnotify). Трудно или невозможно получить изменения файла, чтобы сбить с толку ваших охранников. Новые технологии идут с компромиссами, и иногда простое становится трудным.

Давайте начнем.

Первый долг

Мой Gemfile открыт и готов. Я ломаю костяшки пальцев, переворачиваю плечи и начинаю печатать:

 group :test do ... gem 'guard-rspec' end 

Приложение Rails, над которым я работаю, живет в контейнере с именем «web». Он взаимодействует с базой данных PostgreSQL, рабочим для фоновых заданий и поддельным почтовым сервером. Все организовано с помощью docker-compose :

 $ docker-compose run web bundle install 

Текст пролетает, когда моя система устанавливает Guard. Теперь мне нужен Guardfile :

 $ docker-compose run web bundle exec guard init 

С этим все должно быть готово:

 $ docker-compose run web bundle exec guard 

Меня приветствует знакомая подсказка:

 02:39:05 - INFO - Guard::RSpec is running 02:39:06 - INFO - Guard is now watching at '/app' Frame number: 0/0 [1] guard(main)> 

Я нажимаю клавишу ввода, и мои тесты начинают выполняться. Они дополняются серией приятных зеленых точек, и я не могу удержаться от улыбки. Я открываю модель с помощью vim и сохраняю. Я смотрю на охрану и …

Громко как шепот

Давайте вернемся на минуту. Это развитие происходит в OSX. Docker не работает на OSX. Он работает только на Linux и Linux. Запуск на OSX означает использование небольшой виртуальной машины Linux, удобно упакованной как boot2docker .

Я сказал, что это происходит в OSX. По правде говоря, вся моя работа происходит в OSX. Это мой дом. Здесь я храню свои точечные файлы. Я не хочу работать в виртуальной машине. К счастью, docker-compose понимает мое положение и монтирует локальные каталоги в контейнеры.

Где был я? Ах да, я сохранил свою модель и тесты должны быть запущены. Они не.

Обычно это приводит к бурному поиску в Google. Там нет необходимости в этом. Я знаю, что случилось. Guard опирается на уведомления файловой системы. Установленные тома (в Virtual Box) изменяют файлы под покровом темноты и никому не говорят о том, что они сделали. Охрана молча ждет, блаженно не подозревая об изменениях.

Для этого есть полное решение проблемы. Я пролистываю документацию в поисках того, что мне нужно.

 $ docker-compose run web bundle exec guard --force-polling 

Теперь guard вручную проверяет наличие изменений в каждом файле раз в секунду. Я переключаюсь обратно в редактор и снова сохраняю. Модель тестирует молнию, и вентилятор в моем ноутбуке оживает.

Кто следит за наблюдателями

Мой поклонник настолько громкий, что боюсь, что мой компьютер может взлететь Опрос файлов является более интенсивным, чем я ожидал.

activity_monitor

Более 100% процессора? Это никогда не сработает. Если смотреть вещи так дорого, мне нужно быть осторожным с тем, что я смотрю. Я открываю установленный по умолчанию Guardfile . Он настроен на просмотр всего, что мне может понадобиться, и имеет количество строк, чтобы доказать это. Я начинаю удалять строки в массе.

Я снова начинаю guard и мой поклонник по-прежнему звучит так, будто выдает все, что у него есть. Похоже, работает, хотя. В момент слабости я считаю, что наушники от Амазонки подавляют шум. Я избавляюсь от этой мысли.

Вопрос времени

Я смотрю через экран, пытаясь придумать лучший способ. Момент из моего прошлого всплывает, что может быть решением. На работе, которая у меня была, мы использовали код с помощью rsync. Это почти та же проблема. Это может просто сработать.

Я сразу начинаю думать о том, что должно произойти. Мне нужно установить Rsync в Docker VM. Конечно, они выпускают новые изображения, так что это нужно будет делать каждый раз. Мне понадобится простой способ повторить установку. Я не могу не задаться вопросом, что потребуется, чтобы заставить его работать в контейнерах на виртуальной машине. Правда в том, что я понятия не имею.

Операции никогда не были моей силой, и это показывает. Я знаю решение, которое работало на меня в прошлом. Я надеюсь, что кто-то другой уже сделал это.

Я переключаюсь на Firefox и начинаю поиск. Я перехожу по ссылкам, просматриваю ответы Stack Overflow и попадаю в проект под названием docker-osx-dev . Он пересылает локальные файлы на виртуальную машину, а его сопровождающий, Евгений Брикман, уже обработал сложные части.

Я устанавливаю docker-osx-dev и надеюсь, что он работает как рекламируется. Стена вывода показывает синхронизацию файлов и дает мне немного уверенности. Я начинаю guard без опроса и сохраняю свою модель еще раз. Мои тесты запускаются. Мой поклонник молчит. Мои руки поднялись в воздух. Я люблю эту часть.

Parallels

Подстрекаемый триумфом я продолжаю. Мои тесты идут, но между запусками есть заметная задержка. Моя интуиция говорит, что это загрузка Rails.

Задержка загрузки Rails — это хорошо известная проблема с хорошо известным решением. Rails теперь поставляется с Spring, чтобы решить эту проблему. Он сохраняет копию Rails, работающую в фоновом режиме, а затем разветвляет процесс при необходимости.

Я открываю свой Guardfile и добавляю spring к команде, используемой для запуска rspec :

 guard :rspec, cmd: "bundle exec spring rspec" do ... end 

Уверенный в моем исправлении я начинаю guard :

 03:32:35 - INFO - Running all specs Version: 1.3.6 Usage: spring COMMAND [ARGS] Commands for spring itself: binstub Generate spring based binstubs. Use --all to generate a binstub for all known commands. help Print available commands. status Show current status. stop Stop all spring processes for this project. Commands for your application: rails Run a rails command. The following sub commands will use spring: console, runner, generate, destroy, test. rake Runs the rake command 

Дерьмо. Похоже, что spring должна знать о команде, и она не знакома с rspec . Я не первый, кто сделает это. Вернуться в Google.

Сообщество снова приходит с spring-commands-rspec . Я добавляю его в свой Gemfile , делаю другую bundle install , и guard запускается без нареканий. Я снова сохраняю модель и тесты запускаются. Еще один сохранения, еще один запуск, и задержка исчезла.

Все хорошее…

Я глубоко вздыхаю и киваю головой. Изменения фиксируются с помощью небольшого сообщения, которое вряд ли представляет усилия. Я не могу не думать о тех, на чьих плечах я стою. Не гигантов, а обычных людей. Это довольно драматичная мысль, учитывая, что мне удалось запустить Guard. Не то чтобы я спас мир. Тем не менее, я наслаждаюсь моментом и надеюсь, что мои плечи удастся удержать других. Уже поздно, и мне нужно успокоиться, прежде чем пытаться уснуть. После такого похода мне нужно что-то посмотреть. Если бы я только мог понять, что.