Docker-Compose постоянных данных MySQL

156

Я не могу сохранить данные MySQL, если я запускаю $ docker-compose downсо следующими.yml

version: '2'
services:
  # other services

  data:
    container_name: flask_data
    image: mysql:latest
    volumes:
      - /var/lib/mysql
    command: "true"

  mysql:
    container_name: flask_mysql
    restart: always
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: 'test_pass' # TODO: Change this
      MYSQL_USER: 'test'
      MYSQL_PASS: 'pass'
    volumes_from:
      - data
    ports:
      - "3306:3306"

Насколько я понимаю, в моем dataконтейнере с использованием volumes: - /var/lib/mysqlсопоставляется с моим каталогом локальных машин, где MySQL хранит данные в контейнере, и из-за этого сопоставления данные должны сохраняться, даже если контейнеры уничтожены. И mysqlконтейнер является просто клиентским интерфейсом в БД и может видеть локальный каталог из-заvolumes_from: - data

Попытка этого ответа, и он не работал. Docker-Compose Постоянная проблема с данными

РЕДАКТИРОВАТЬ

Изменил мою , .ymlкак показано ниже , и создал реж ./dataно теперь , когда я бегу docker-compose up --buildв mysqlначало контейнера обыкновение бросает ошибку говоря

  data:
    container_name: flask_data
    image: mysql:latest
    volumes:
      - ./data:/var/lib/mysql
    command: "true"

  mysql:
    container_name: flask_mysql
    restart: always
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: 'test_pass' # TODO: Change this
      MYSQL_USER: 'test'
      MYSQL_PASS: 'pass'
    volumes_from:
      - data
    ports:
      - "3306:3306"


flask_mysql | mysqld: Can't create/write to file '/var/lib/mysql/is_writable' (Errcode: 13 - Permission denied)
flask_mysql | 2016-08-26T22:29:21.182144Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
flask_mysql | 2016-08-26T22:29:21.185392Z 0 [ERROR] --initialize specified but the data directory exists and is not writable. Aborting.
Адам
источник

Ответы:

223

Контейнер данных - излишний обходной путь. Объемы данных помогут вам. Измените свой docker-compose.ymlна:

version: '2'
services:
  mysql:
    container_name: flask_mysql
    restart: always
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: 'test_pass' # TODO: Change this
      MYSQL_USER: 'test'
      MYSQL_PASS: 'pass'
    volumes:
      - my-datavolume:/var/lib/mysql
volumes:
  my-datavolume:

Докер создаст для вас том в /var/lib/docker/volumesпапке. Этот объем сохраняется до тех пор, пока вы не печатаетеdocker-compose down -v

Ohmen
источник
18
Начиная с MySQL 5.7.6 (снова) будут проблемы с разрешениями с образом mysqlDocker. Вместо этого вы можете использовать mariadbобраз Docker, который безупречно работает с томами Docker.
Петерино,
Это решение сработало для меня. Пара замечаний / уточнений: 1. когда вы используете вышеупомянутую конфигурацию в docker-compose.yml и развертываете свой стек служб с помощью «docker stack deploy -c docker-compose.yml mystack», нет необходимости создавать том вручную, он будет автоматически создан как / var / lib / docker / volume / mystack_my-datavolume (обратите внимание, что он добавляет «mystack_» к имени тома). 2. Мне не нужно было менять разрешения для моего каталога. Даже если у меня есть файлы, принадлежащие mysql: root в моем контейнере, они были созданы как 27: root на моем хосте Docker без проблем.
Джои Кот
10
Почему вы хотите сохранить его var/lib/docker/volumesвместо того, чтобы иметь директорию в папке вашего проекта, как data/mysql?
Крестный отец
@TheGodfather Я полагаю, если вы не хотите развертывать данные MySQL на своем рабочем компьютере; в противном случае, это очень здравая идея, объединяющая все.
Дункан
1
@ Я думаю, потому что я чувствую себя более уверенно, когда все части моего приложения и данные каким-то образом хранятся вместе, и у меня нет зависимости от какого-то тома откуда-то
The Godfather
53

Есть 3 способа:

Первый способ

Вам необходимо указать каталог для хранения данных MySQL на вашем хост-компьютере . Затем вы можете удалить контейнер данных. Ваши данные MySQL будут сохранены в вашей локальной файловой системе.

Определение контейнера Mysql должно выглядеть так:

mysql:
  container_name: flask_mysql
  restart: always
  image: mysql:latest
  environment:
    MYSQL_ROOT_PASSWORD: 'test_pass' # TODO: Change this
    MYSQL_USER: 'test'
    MYSQL_PASS: 'pass'
volumes:
 - /opt/mysql_data:/var/lib/mysql
ports:
  - "3306:3306"

Второй способ

Было бы зафиксировать контейнер данных перед вводом docker-compose down:

docker commit my_data_container
docker-compose down

Третий путь

Также вы можете использовать docker-compose stopвместо docker-compose down(тогда вам не нужно фиксировать контейнер)

Бухаров Сергей
источник
Разве я не могу просто иметь, volumes: - /var/lib/mysqlпотому что он отображает, HOST:CONTAINERи если вы не указываете двоеточие, он отображает один и тот же каталог?
Адам
Не. к сожалению, в этом случае докер отображает эту директорию контейнера в случайную папку хоста, как/var/lib/docker/volumes/ec3c543bc92f114c2c568733541e89381881e5a62996d7084e07793f86280535
Бухаров Сергей
Хорошо, я думал, что volumes: - /var/lib/mysqlбыло эквивалентноvolumes: - /var/lib/mysql:/var/lib/mysql
Адам
ваш путь не будет работать, потому что Docker не передает данные из томов в образ. см. github.com/moby/moby/issues/6999
Омен
13

Вы должны создать отдельный том для данных MySQL.

Так это будет выглядеть так:

volumes_from:
  - data
volumes:
  - ./mysql-data:/var/lib/mysql

И нет, /var/lib/mysqlэто путь внутри вашего контейнера mysql, который не имеет ничего общего с путем на вашем хост-компьютере. Ваш хост-компьютер может вообще не иметь mysql. Таким образом, цель состоит в том, чтобы сохранить внутреннюю папку из контейнера MySQL.

Дмитрий Малышенко
источник
Разве это не отличалось бы от замены моего volumesпод контейнером данных тем, что вы положили под свой volumesи просто имели volumes_from: - dataдля mysql? Также попытался это и новая ошибка. Говорит, что каталог существует, но не доступен для записи, и mysqlконтейнер не запустится.
Адам
Конечно, вы должны создать локальную папку с путем ./mysql-data (или что бы вы не ставили перед точкой с запятой)
Дмитрий Малышенко
Смотрите мое редактирование. Не получил, прежде чем вы прокомментировали. Но создал местный реж. Похоже, сейчас есть проблема с разрешениями.
Адам
ОШИБКА. Служба «mysql» монтирует тома из «данных», которые не являются именем службы или контейнера.
Массимилиано Арионе
10

На самом деле это путь, и вы должны указать правильный путь для этого. Если каталог данных находится в каталоге , то вместо того , my-dataследует отметить ./my-data, в противном случае это даст вам эту ошибку mysqlи mariadbтакже.

volumes:
 ./my-data:/var/lib/mysql
codelearner
источник