[Из песочницы] Docker контейнеры для web-разработчика под OS X
Всю свою текущую разработку я веду, используя docker контейнеры, и если под Linux такой подход не вызывает никаких проблем, то под OS X некоторые моменты могут отнять невероятное количество сил и времени.Об одном из таких моментов я и хочу рассказать.В моем случае разработка с иcпользованием docker выглядит так: на контейнере поднят весь необходимый мне софт. Папки с рабочим проектом смаплены с хост системы в контейнер. В контейнере для автобилда настроен либо grunt с grunt-contrib-watch, либо watchify, либо порой просто висит скриптик, использующий inotify-tools.
В случае веб-разработки цикл простой: я правлю на маке файлы проекта, watch утилитки стартуют билд, livereload обновляет web страничку. Но при таком подходе сразу возникает проблема — файловая система vboxsf входящая в Virtualbox Guest Additions невероятно медленная, отсюда:
watch утилитки начинают грузить систему процентов на 200; даже небольшая сборка — например простая конкатенация файлов начинает занимать десятки секунд. Это — неприемлемо.Быстрое гугление показало, что nfs работает в разы быстрее, чем vboxfs. Настроить nfs сервер под OSX быстро и легко.
#включить nfs сервер sudo nfsd enable #отредактировать файл с папками для шаринга sudo vi /etc/exports # добавить папки которые надо сделать доступными например /Users/user/my_web_project -mapall=ice #проверить что нет ошибок sudo nfsd checkexports #проверить что папки подцпились showmount -e Дальше надо передать в docker ip адрес OSX хоста, чтобы можно было подцепить файловую систему:
#получить ip хоста висящего на интерфейсе virtual box HOST_IP=`ifconfig vboxnet0 | tail -1 | awk '{print $2}'` #передать в контейнер docker run --name smap -p 3080:3080 -e HOST_IP=»$HOST_IP» -d -t sentimeta/node_scikit_image В контейнере надо накатить nfs клиента и замаунтить нужные папки:
#накатить клиента sudo apt-get update sudo apt-get install nfs-common #замаунтить nfs osx папку sudo mount -o nolock »$HOST_IP»:/Users/user/my_web_project ~/my_web_project И действительно, две проблемы уходят:
загрузка процессора около ноля; билд теперь идет очень быстро. Но появляется новая проблема — inotify события файловой системы nfs, на которых сидят все watch утилитки, проходят, но с задержками по 10–20 секунд.Это — неприемлемо.
Поэтому было принято решение начать ловить inotify события на host машине и передавать информацию в docker контейнер.
Для решения проблемы я использовал следующие утилитки:
Сторона докераВешаем http веб сервер на 3080 порт:
watch -n0 'printf «HTTP/1.1 200 OK\n\n$(date && touch /home/user/my_web_project/watchhelper.tmp)\n» | nc -l -p 3080 >/dev/null && date' Это самый настоящий веб сервер на bash висящий на 3080 порту, на каждый запрос он выполняет команду date и touch файла watchhelper.tmp, который надо положить вне исходников вашего проекта, который надо добавить в watch. Ниже я поясню, почему вне исходников проекта.touch команда «трогая» файл вызывает inotify событие приводяещее к сборке; date команда удобна для тестирования, ее вывод и есть ответ этого сервера. Проверить, что работает, можно так: И, ура — в браузере видим время, а в контейнере — мгновенное срабатывание watch утилиток.Сторона OSXУстанавливаем fswatch:
brew install fswatch Запускаем:
fswatch-run /Users/user/my_web_project/src «curl http://`boot2docker ip 2>&1 | sed -n 2,2p | awk -F' ' '{print $9}'`:3080» Теперь при изменении любого файла в папке /Users/user/my_web_project/src будет вызван поднятый в контейнере веб сервер, который «потрогает» файл, что в свою очередь вызовет билд.
Файл watchhelper.tmp надо расположить вне исходников проекта по причине, что nfs все-таки пропускает inotify события и лежащий в исходниках файл вызовет вечный цикл curl touch touch событий.
Различные вопросы настройки докер контейнеров под макось я нерегулярно добавляю в проект на гитхабе istarkov/docker.
Если тема вызовет отклик — напишу еще несколько заслуживающих внимания вещей при использовании docker контейнеров при разработке на OS X.