Docker-Compose trwałe dane MySQL

156

Wydaje się, że nie mogę uzyskać danych MySQL, aby przetrwać, jeśli uruchomię $ docker-compose downz następującymi.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"

Rozumiem, że w moim datakontenerze za pomocą volumes: - /var/lib/mysqlmapuje go do katalogu mojego lokalnego komputera, w którym mysql przechowuje dane do kontenera i z powodu tego mapowania dane powinny pozostać, nawet jeśli kontenery są zniszczone. A mysqlkontener jest tylko interfejsem klienta do bazy danych i może zobaczyć katalog lokalny z powoduvolumes_from: - data

Próbowałem tej odpowiedzi i to nie zadziałało. Problem z trwałymi danymi Docker-Compose

EDYTOWAĆ

Zmieniłem .ymljak pokazano poniżej i stworzył dir ./data, ale teraz, kiedy biegnę docker-compose up --buildna mysqlpoczątek pojemnik przyzwyczajenie wyrzuca błąd mówiąc

  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.
Adam
źródło

Odpowiedzi:

223

Kontener danych jest zbędnym obejściem. Woluminy danych załatwią sprawę za Ciebie. Zmień docker-compose.ymlna:

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:

Docker utworzy dla Ciebie wolumin w /var/lib/docker/volumesfolderze. Ten wolumin utrzymuje się tak długo, jak długo nie piszeszdocker-compose down -v

Ohmen
źródło
18
Począwszy od MySQL 5.7.6 pojawią się (znowu) problemy z uprawnieniami do mysqlobrazu Dockera. Zamiast tego możesz użyć mariadbobrazu Docker, który działa bezbłędnie z woluminami Docker.
Peterino,
To rozwiązanie zadziałało dla mnie. Kilka dodatkowych uwag / uściśleń: 1. Kiedy używasz powyższej konfiguracji w docker-compose.yml i wdrażasz swój stos usług za pomocą „docker stack deploy -c docker-compose.yml mystack”, nie ma potrzeby tworzenia wolumin ręcznie, zostanie automatycznie utworzony jako / var / lib / docker / volume / mystack_my-datavolume (zwróć uwagę, że do nazwy wolumenu dodaje się „mystack_”). 2. Nie musiałem zmieniać uprawnień do mojego katalogu. Nawet jeśli mam pliki należące do mysql: root w moim kontenerze, zostały one utworzone jako 27: root na moim hoście Docker bez problemów.
Joey Cote
10
Dlaczego kiedykolwiek chcesz go przechowywać var/lib/docker/volumeszamiast katalogu w folderze projektu data/mysql?
The Godfather
@TheGodfather Domyślam się, że nie chcesz wdrażać danych MySQL na swojej maszynie produkcyjnej; w przeciwnym razie to bardzo rozsądny pomysł, aby wszystko trzymać razem.
Duncan
1
@louhow myślę, ponieważ czuję się bardziej pewny siebie, gdy wszystkie części mojej aplikacji i dane są w jakiś sposób przechowywane razem i nie mam żadnych zależności od jakiegoś woluminu skądś
Ojciec chrzestny
53

Istnieją 3 sposoby:

Pierwszy sposób

Musisz określić katalog do przechowywania danych mysql na komputerze hosta . Następnie możesz usunąć kontener danych. Twoje dane mysql zostaną zapisane w lokalnym systemie plików.

Definicja kontenera MySQL musi wyglądać następująco:

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"

Drugi sposób

Byłoby zatwierdzenie kontenera danych przed wpisaniem docker-compose down:

docker commit my_data_container
docker-compose down

Trzeci sposób

Możesz także użyć docker-compose stopzamiast docker-compose down(wtedy nie musisz zatwierdzać kontenera)

Bukharov Sergey
źródło
Czy nie mogę po prostu mieć, volumes: - /var/lib/mysqlponieważ mapuje HOST:CONTAINERi jeśli nie określisz dwukropkiem, mapuje ten sam katalog?
Adam
Nie. niestety w tym przypadku docker mapuje ten katalog kontenera do losowego folderu hosta, takiego jak/var/lib/docker/volumes/ec3c543bc92f114c2c568733541e89381881e5a62996d7084e07793f86280535
Bukharov Sergey
Okay, myślałem, że volumes: - /var/lib/mysqlto odpowiednikvolumes: - /var/lib/mysql:/var/lib/mysql
Adam
Twój trzeci sposób nie zadziała, ponieważ docker nie przekazuje danych z woluminów do obrazu. patrz github.com/moby/moby/issues/6999
Ohmen
13

Musisz utworzyć osobny wolumin dla danych mysql.

Więc będzie to wyglądać tak:

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

I nie, /var/lib/mysqljest to ścieżka wewnątrz kontenera mysql i nie ma nic wspólnego ze ścieżką na komputerze hosta. Twoja maszyna hosta może nawet w ogóle nie mieć mysql. Dlatego celem jest utrwalenie wewnętrznego folderu z kontenera mysql.

Dmitrij Malyshenko
źródło
Czy nie byłoby to nie różni się od zmieniam volumesw kontenerze danych do tego, co można umieścić pod twoimi volumesi po prostu miał volumes_from: - dataza mysql? Podjęto również próbę tego, a następnie nowy błąd. Mówi, że dir istnieje, ale nie można go zapisać, a mysqlkontener nie będzie działać.
Adam
Oczywiście musisz utworzyć folder lokalny ze ścieżką ./mysql-data (lub cokolwiek byś umieścił przed średnikiem)
Dmitry Malyshenko
Zobacz moją edycję. Nie dostałem tego, zanim skomentowałeś. Ale stworzył lokalny reż. Wygląda na to, że jest teraz problem z pozwoleniem.
Adam
BŁĄD: Usługa „mysql” montuje woluminy z „danych”, które nie są nazwą usługi lub kontenera.
Massimiliano Arione
10

Właściwie to jest ścieżka i powinieneś wspomnieć o prawidłowej ścieżce, aby to zadziałało. Jeśli twój katalog danych znajduje się w bieżącym katalogu, zamiast tego my-datapowinieneś wspomnieć ./my-data, w przeciwnym razie da ci ten błąd w mysqli mariadbtakże.

volumes:
 ./my-data:/var/lib/mysql
codelearner
źródło