Как сохранить состояние (данные) в Docker-контейнере?

«Как сохранить состояние (данные) в Docker-контейнере?» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для сохранения данных, которые должны пережить остановку или удаление контейнера, я использую механизмы, предоставляемые Docker, а не полагаюсь на внутреннюю файловую систему контейнера.

Основные подходы:

  1. Тома (Docker Volumes) — предпочтительный способ, управляемый Docker.

    • Данные хранятся в области, контролируемой Docker (обычно /var/lib/docker/volumes/).
    • Тома можно создавать, управлять и подключать независимо от жизненного цикла контейнеров.
      # Создаём том
      docker volume create myapp_data
      # Запускаем контейнер и монтируем том
      docker run -d --name myapp -v myapp_data:/var/lib/app/data myapp_image
      # Даже если контейнер 'myapp' удалить, данные в томе 'myapp_data' сохранятся.
  2. Bind Mounts — привязка конкретной директории с хоста в контейнер.

    • Использую, когда нужно, чтобы контейнер работал с данными, уже существующими на хосте, или для разработки (монтирую исходный код).
      # Монтируем директорию хоста в контейнер
      docker run -d --name myapp -v /host/path/to/data:/container/path myapp_image
  3. tmpfs Mounts — данные хранятся только в оперативной памяти хоста.

    • Идеально для временных, чувствительных данных, которые не должны попадать на диск.
      docker run -d --name myapp --tmpfs /app/cache myapp_image

Практический пример с Docker Compose:

version: '3.8'
services:
  database:
    image: postgres:15
    volumes:
      # Используем именованный том для хранения данных БД
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: example

volumes:
  postgres_data: # Том будет создан автоматически

Важно: Без использования томов или bind mounts все изменения, сделанные внутри файловой системы контейнера, теряются при его удалении.