Docker volumes

При необходимости изменения/обновления контейнеров их принято убивать и пересоздавать, соответственно все данные находящиеся внутри контейнера теряются. Появляется потребность в механизме сохранения важных данных. На помощь приходят т.н. тома (volumes) — места для длительного хранения файлов, обычно это БД, логи и т.п.

Например у нас есть контейнер PostgreSQL, нам необходимо обновить его конфигурацию и пересоздать без потери данных. Идея в том, чтобы папку с данными в контейнере PostgreSQL хранить отдельно от контейнера, а при необходимости ее туда монтировать.

Исторически сложилось несколько способов это сделать, я выделяю 4:

  1. Bind-mounts. Монтирование внешних папок параметром -v /host:/container. Тут все просто. Папка с хостовой машины монтируется (пробрасывается) в контейнер. В итоге получаем что-то вроде общей папки для хоста и контейнера. Таким способом удобно передавать данные в любую сторону. Очевидная проблема с правами на монтированные файлы/папки.
  2. Data-only containers. Создание специального контейнера с использованием его файловой системы для хранения данных параметром —volumes-from. Создается контейнер, в котором в нужной папке будут лежать данные (по факту где-то в /var/lib/docker/vfs/dir/..). В таком случае не надо заботится по поводу прав и т.п. на файлы в отличии от первого способа. Данный подход не является рекомендованным, следует использовать Named volumes.
  3. Named volumes. В отличии от data-only не создается контейнер (как следствие не нужен базовый образ), размещается где-то в /var/lib/docker/volumes/.., доступен по имени. Вот хорошая статья.
  4. VOLUME в Dockerfile. При каждом создании контейнера создается новый том (docker volume ls). Чтобы использовать его повторно необходимо создать другой контейнер и указать –volumes-from `предыдущий_контейнер`. Слабо представляю, как это использовать на практике, надо разбираться. Пример: создаю образ, указываю VOLUME /var/www, создаю контейнер, сохраняю туда что-то, удаляю контейнер, пересоздаю с того же образа, данные пропали. Это значит что после удаления контейнера том не сохраняется и не перемонтируется. На эту тему есть хорошие статьи, но не так просто понять их суть: http://container42.com/2014/11/03/docker-indepth-volumes/, http://stackoverflow.com/questions/25311613/docker-mounting-volumes-on-host, http://stackoverflow.com/questions/34809646/what-is-the-purpose-of-volume-in-dockerfile.

Вывод: способ использования томов зависит от задачи, для переноса кода приложения и необходимых файлов удобно использовать Bind-mounts, для хранения данных БД удобней пользоваться Named volumes. Что касается VOLUME в Dockerfile — надо разбираться.