Докер, постоянная синхронизация Mysql базы с контейнера на локаль

изучаю докер и не могу никак понять вещь, мне нужно чтобы была синхронизация базы данных с контейнера на локаль. Я пробовал так:

    volumes:
  - ./database_on_local:/var/lib/mysql

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

Структура файлов такая:

req.txt
venv
database:
  dockerfile
docker-compose.yaml

Код в Dockerfile:

FROM mariadb


COPY dump.sql dump.sql
RUN /bin/bash -c "/usr/bin/mysqld_safe --skip-grant-tables &" && \
  sleep 5 && \
  mysql -u root -e "CREATE DATABASE bot_different_utilities" && \
  mysql -u root bot_different_utilities < /dump.sql

Код в docker-compose.yaml:

version: '3.1'

services:

  db:
    build: ./database
    restart: always
    volumes:
      - ./database_on_local:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: root

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

Можно конечно делать дамп через скрипты каждую минуту, или ещё какой-то костыль приделать, если конечно то, что я хочу возможно. Заранее благодарен за ответ.


Ответы (2 шт):

Автор решения: Roman Konoval

Поведение, которое вы получаете - ожидаемое.

Инструкции из Dockerfile выполняются по команде docker build .... В результате создается образ, который содержит файловую систему. В вашем случае в файловой системе вы создаете файлы БД.

Далее по команде docker run ... этот образ используется и если вы используете bind volumes, то директория с хоста монтируется в файловую систему контейнера перекрывая то, что там уже было.

Докер не умеет то, что вы хотите. Идея такая, что в контейнере не нужно хранить данные, контейнер можно в любой момент убить или перезапустить. Его состояние не сохраняется. Все важные данные нужно хранить в присоединяемых томах (volumes).

Правильным решением будет запуск создания БД не на этапе сборки образа, а уже на этапе запуска контейнера.

→ Ссылка
Автор решения: antipups

Решил проблему так, для использования дампа вам потребуется прописать вот такой код в волюмях:

  db:
#    build: ./database
    image: mariadb
    restart: always
    volumes:
      - ./database_on_local:/var/lib/mysql
      - ./dump.sql:/docker-entrypoint-initdb.d/dump.sql
    environment:
      MYSQL_ROOT_PASSWORD: root

Первое - синхронизация с хранилищем железа, второе - инициализация вашего дампа. (не забудьте прописать CREATE DATABASE db_name и USE db_name ибо не все дамперы это делают)

→ Ссылка