Docker-Componer datos persistentes MySQL

156

Parece que no puedo lograr que los datos de MySQL persistan si ejecuto $ docker-compose downlo siguiente.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"

Entiendo que en mi datacontenedor, el uso lo volumes: - /var/lib/mysqlasigna al directorio de mi máquina local, donde mysql almacena datos en el contenedor y, debido a esta asignación, los datos deberían persistir incluso si los contenedores se destruyen. Y el mysqlcontenedor es solo una interfaz de cliente en el db y puede ver el directorio local debido avolumes_from: - data

Intenté esta respuesta y no funcionó. Problema de datos persistentes de Docker-Compose

EDITAR

Cambié mi .ymlcomo se muestra a continuación y creé un directorio, ./datapero ahora cuando ejecuto docker-compose up --buildel mysqlcontenedor no comienza a arrojar el error diciendo

  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.
Adán
fuente

Respuestas:

223

El contenedor de datos es una solución superflua. Los volúmenes de datos harían el truco por usted. Altera tu docker-compose.ymla:

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 creará el volumen para usted en la /var/lib/docker/volumescarpeta. Este volumen persiste mientras no esté escribiendodocker-compose down -v

Oh hombres
fuente
18
Comenzando con MySQL 5.7.6 (nuevamente) habrá problemas de permisos con la mysqlimagen Docker. En su lugar, puede usar la mariadbimagen Docker, que funciona perfectamente con los volúmenes Docker.
Peterino
Esta solución funcionó para mí. Un par de notas al margen / precisiones: 1. cuando utiliza la configuración anterior en docker-compose.yml y despliega su pila de servicios utilizando "docker stack deploy -c docker-compose.yml mystack", no es necesario crear el volumen manualmente, se creará automáticamente como / var / lib / docker / volume / mystack_my-datavolume (observe que antepone "mystack_" al nombre del volumen). 2. No tuve que cambiar los permisos en mi directorio. Incluso si tengo archivos propiedad de mysql: root en mi contenedor, se crearon como 27: root en mi host Docker sin problemas.
Joey Cote
10
¿Por qué alguna vez quieres almacenarlo en var/lib/docker/volumeslugar de tener un directorio en la carpeta de tu proyecto data/mysql?
El padrino
@TheGodfather Supongo que si no desea implementar datos MySQL en su máquina de producción; de lo contrario, es una buena idea mantener todo junto.
Duncan
1
@louhow creo porque me siento más seguro cuando todas las partes de mi aplicación y los datos se almacenan de alguna manera juntas, y no tengo dependencias de algún volumen de algún lugar
The Godfather,
53

Hay 3 formas:

Primera forma

Necesita especificar el directorio para almacenar datos mysql en su máquina host . Luego puede eliminar el contenedor de datos. Sus datos mysql se guardarán en su sistema de archivos local.

La definición del contenedor Mysql debe verse así:

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"

Segunda forma

Sería confirmar el contenedor de datos antes de escribir docker-compose down:

docker commit my_data_container
docker-compose down

Tercera forma

También puede usar en docker-compose stoplugar de docker-compose down(entonces no necesita confirmar el contenedor)

Bukharov Sergey
fuente
¿No puedo simplemente volumes: - /var/lib/mysqlporque se asigna HOST:CONTAINERy si no especificas con dos puntos, se asigna el mismo directorio?
Adam
No. desafortunadamente en este caso, la ventana acoplable asigna este directorio contenedor a una carpeta de host aleatoria como/var/lib/docker/volumes/ec3c543bc92f114c2c568733541e89381881e5a62996d7084e07793f86280535
Bukharov Sergey
Bien, pensé que volumes: - /var/lib/mysqlera equivalente avolumes: - /var/lib/mysql:/var/lib/mysql
Adam
su tercer camino no funcionará porque la ventana acoplable no confirma los datos de los volúmenes a la imagen. ver github.com/moby/moby/issues/6999
Ohmen
13

Debe crear un volumen separado para los datos de mysql.

Entonces se verá así:

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

Y no, /var/lib/mysqles una ruta dentro de su contenedor mysql y no tiene nada que ver con una ruta en su máquina host. Su máquina host puede incluso no tener mysql en absoluto. Entonces, el objetivo es conservar una carpeta interna de un contenedor mysql.

Dmitry Malyshenko
fuente
No sería esto no es diferente de cambiar mi volumesbajo el contenedor de datos a lo que se pone debajo de la volumesy simplemente tenía volumes_from: - datapara mysql? También intenté esto y thew un nuevo error. Dice que existe el directorio pero que no se puede escribir y que el mysqlcontenedor no se ejecutará.
Adam
Por supuesto, debe crear una carpeta local con una ruta ./mysql-data (o lo que sea que ponga antes del punto y coma)
Dmitry Malyshenko
Mira mi edición. No lo recibí antes de comentar. Pero creó dir local. Parece que hay un problema de permiso ahora.
Adam
ERROR: El servicio "mysql" monta volúmenes de "datos", que no es el nombre de un servicio o contenedor.
Massimiliano Arione
10

En realidad, esta es la ruta y debe mencionar una ruta válida para que esto funcione. Si su directorio de datos está en el directorio actual, en lugar de lo my-dataque debería mencionar ./my-data, de lo contrario, le dará ese error mysqly mariadbtambién.

volumes:
 ./my-data:/var/lib/mysql
codelearner
fuente