Мне никогда не нравилось, как проекты загрязняют мою систему. Библиотеки, базы данных, очереди сообщений, вы называете это, и мне пришлось установить его. В этой общей вселенной миры сталкиваются только с вопросом времени. Два проекта требуют отдельного 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
вручную проверяет наличие изменений в каждом файле раз в секунду. Я переключаюсь обратно в редактор и снова сохраняю. Модель тестирует молнию, и вентилятор в моем ноутбуке оживает.
Кто следит за наблюдателями
Мой поклонник настолько громкий, что боюсь, что мой компьютер может взлететь Опрос файлов является более интенсивным, чем я ожидал.
Более 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. Не то чтобы я спас мир. Тем не менее, я наслаждаюсь моментом и надеюсь, что мои плечи удастся удержать других. Уже поздно, и мне нужно успокоиться, прежде чем пытаться уснуть. После такого похода мне нужно что-то посмотреть. Если бы я только мог понять, что.