Docker-撰写持久数据MySQL

Ada*_*dam 120 docker docker-compose

如果我运行$ docker-compose down以下内容,我似乎无法保持MySQL数据持续存在.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"
Run Code Online (Sandbox Code Playgroud)

我的理解是在我的data容器中使用volumes: - /var/lib/mysqlmap将它映射到我的本地机器目录,其中mysql将数据存储到容器中,并且由于这种映射,即使容器被销毁,数据也应该保持不变.而mysql容器只是进入数据库的客户端接口,因为可以看到本地目录volumes_from: - data

尝试这个答案,它没有用.Docker-撰写持久性数据问题

编辑

改变了我.yml如下图所示,创建了目录./data,但现在当我运行docker-compose up --buildmysql容器无法启动抛出错误说

  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.
Run Code Online (Sandbox Code Playgroud)

Ohm*_*men 180

数据容器是一个多余的解决方法.数据量可以帮到你.改变你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:
Run Code Online (Sandbox Code Playgroud)

Docker将在/var/lib/docker/volumes文件夹中为您创建卷.只要您不打字,此卷就会持续存在docker-compose down -v

  • 从MySQL 5.7.6开始,将再次使用`mysql` Docker镜像[权限问题](https://github.com/docker-library/mysql/issues/69).你可以使用Docker卷的`mariadb` Docker镜像,[它可以完美地工作](https://github.com/docker-library/mysql/issues/69#issuecomment-269537249). (15认同)
  • 为什么你想将它存储在`var/lib/docker/volumes`而不是像`data/mysql`这样的项目文件夹中有目录? (7认同)
  • @louhow我认为是因为当我的应用程序和数据的*所有*部分以某种方式存储在一起时,我觉得自己更有信心,并且我对某处的某些卷没有依赖性 (4认同)
  • @TheGodfather 我的猜测是,如果您不想将 MySQL 数据部署到您的生产机器;否则,将所有东西放在一起是一个非常合理的想法。 (2认同)
  • @TheGodfather - 这并不能完全回答您的问题,但我对使用此解决方案持谨慎态度,因为我担心我会无意中执行“docker-compose down”并丢失音量。事实证明,你必须执行 `docker-compose down -v` 才能永久失去你的音量,这让我对整个方法感觉好多了。我认为一个更好的问题可能是,当 docker 可以完全为您处理它时,为什么要自己创建一个目录? (2认同)

Buk*_*gey 42

有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"
Run Code Online (Sandbox Code Playgroud)

第二种方式

将在键入之前提交数据容器docker-compose down:

docker commit my_data_container
docker-compose down
Run Code Online (Sandbox Code Playgroud)

第三种方式

你也可以使用docker-compose stop而不是docker-compose down(那时你不需要提交容器)

  • 您的第三种方法将不起作用,因为 docker 不会将数据从卷提交到映像。请参阅https://github.com/moby/moby/issues/6999 (2认同)

MGL*_*don 12

除了@Ohmen 的回答之外,您还可以添加一个external标志来创建docker compose 之外的数据量。这样 docker compose 就不会尝试创建它。此外,您不必担心在$ docker-compose down -v. 下面的例子来自官方页面

version: "3.8"

services:
  db:
    image: postgres
    volumes:
      - data:/var/lib/postgresql/data

volumes:
  data:
    external: true
Run Code Online (Sandbox Code Playgroud)


Dmi*_*nko 11

您必须为mysql数据创建单独的卷.

所以它看起来像这样:

volumes_from:
  - data
volumes:
  - ./mysql-data:/var/lib/mysql
Run Code Online (Sandbox Code Playgroud)

不,/var/lib/mysql是mysql容器中的路径,与主机上的路径无关.您的主机甚至可能根本没有mysql.因此,目标是从mysql容器中持久保存内部文件夹.


Has*_*eed 8

首先,您需要使用删除所有旧的mysql数据

docker-compose down -v
Run Code Online (Sandbox Code Playgroud)

之后在你的 docker-compose.yml 中添加两行

volumes:
  - mysql-data:/var/lib/mysql
Run Code Online (Sandbox Code Playgroud)

volumes:
  mysql-data:
Run Code Online (Sandbox Code Playgroud)

你最终的 docker-compose.yml 看起来像

version: '3.1'

services:
  php:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 80:80
    volumes:
      - ./src:/var/www/html/
  db:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - mysql-data:/var/lib/mysql

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
volumes:
  mysql-data:
Run Code Online (Sandbox Code Playgroud)

之后使用这个命令

docker-compose up -d
Run Code Online (Sandbox Code Playgroud)

现在您的数据将持久存在,即使使用此命令也不会被删除

docker-compose down
Run Code Online (Sandbox Code Playgroud)

额外:-但如果你想删除所有数据,那么你将使用

docker-compose down -v
Run Code Online (Sandbox Code Playgroud)


cod*_*ner 5

实际上,这是路径,您应该提到有效的路径。如果您的数据目录位于当前目录中,那么my-data您应该提及而不是./my-data,否则它将在mysql和中mariadb也给您带来该错误。

volumes:
 ./my-data:/var/lib/mysql
Run Code Online (Sandbox Code Playgroud)

  • 如果使用正确的话,这两种方式都是有效的。第一个没有路径符号的实际上是一个命名卷,应该在使用之前对其进行初始化。在 docker-compose 文件中,我们可以有一个顶级卷部分来配置名称到主机上特定位置的映射。之后,可以仅通过其名称来引用该卷。 (3认同)