пятница, марта 20, 2015

Разворачиваем приложение на Erlang (cowboy) с помощью Docker.

note: делалось это не для production кода, а с целью самообучения. Некоторые решения могут быть странными. Это получилось от того, что с докером я познакомился буквально на днях. Если кому что-то будет резать глаз - не поленитесь в комментариях написать про ошибку и как сделать правильно, спасибо. Также предполагается, что вы знаете зачем нужен docker.

1. Структура проекта.

Под каждый контейнер выделяю отдельную папку. В корне проекта положим docker-compose.yml (настройки бывшего fig, нынешнего docker-compose).

Получаем такое дерево, в каждом каталоге лежит свой Dockerfile:

  • back - наше erlang приложение
  • front - статические файлы и javascript, в моём случае это React-приложение, которое собирается с помощью webpack.
  • nginx - конфиги для nginx, который будет работать как reverse proxy.
  • pg - скрипты для создания базы данных в postgresql
  • redis - контейнер с redis.
  • sources - контейнер с исходниками.

2. Первый контейнер, sources.

Мне хочется использовать все эти контейнеры для разработки, поэтому мне нужно чтобы исходники проектов внутри контейнеров были теми исходниками, с которыми я работаю, а не их копией. Поэтому создаю контейнер sources, в который через docker-compose будут подключены папки с сырцами.

(Здесь и далее gist с docker-compose.yml это кусочек общего большого файла.)

3. Второй контейнер, pg.

От postgres мне пока требуется всего две вещи: работать с заданным мною паролём и хранить данные в указанной папке. Для этого возьмём docker image из стандартного репозитория. В нём оба вопроса решаются переменными окружения.

4. Третий контейнер, redis.

С редисом всё просто до неприличия. Мне даже неинтересно, где он данные разместит и что с ними будет после перезапуска. (Что и как настроить в противном случае, описано здесь)

5. Четвёртый контейнер, backend.

Тут у меня будет строиться и стартовать erlang-приложение. Исходники приложения будут лежать в /app/backend. Приложение представляет из себя rest и вебсокет хэндлеры на cowboy. Если мне захочется чтобы исходники перегружались на лету в процессе разработки, я подключу в зависимостях пакет sync или live.

6. Пятый контейнер, frontend.

С фронтом всё совсем просто: запускаем webpack в режиме watch, чтобы построив bundle он висел дальше, слушал изменения и достраивал по необходимости.

7. Шестой контейнер, nginx.

Теперь нам нужно поставить на входе nginx, который примет соединение и отправит его в зависимости от типа либо к бэкенду, либо на статический файл. Вопрос лишь в том, как nginx'у узнать адреса серверов. Проблема в том, что переменные окружения в nginx можно использовать только в главном конфиге, но нельзя в модулях, например upstream и location. Поэтому сделаем так, чтобы на запуске контейнера с nginx на лету формировался файл с конфигом:

8. Всё готово.

docker-compose build

docker-compose up

При необходимости прицепиться к запущенным контейнерам и посмотреть логи, пишем docker-compose logs. Если требуется что-то выполнить внутри запущенного контейнера, пишем docker ps, смотрим название контейнера в правом столбце "NAMES", например myapp_nginx_1. И выполняем: docker exec myapp_nginx_1 ls -lR /etc/nginx/


Комментариев нет: