Docker入门教程中缺少什么吗?

时间:2020-05-21 00:24:21

标签: docker docker-compose

我正在从Docker开始入门教程(https://www.docker.com/101-tutorial-Docker Desktop),他们在这里编写了docker-compose:

version: "3.7"

services:
  app:
    image: node:12-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos

  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

问题是MySQL没有创建“ todos”数据库。 然后我的应用程序无法连接到它,给我这个错误:

app_1    | Error: ER_HOST_NOT_PRIVILEGED: Host '172.26.0.2' is not allowed to connect to this MySQL server
app_1    |     at Handshake.Sequence._packetToError (/app/node_modules/mysql/lib/protocol/sequences/Sequence.js:47:14)
app_1    |     at Handshake.ErrorPacket (/app/node_modules/mysql/lib/protocol/sequences/Handshake.js:123:18)
app_1    |     at Protocol._parsePacket (/app/node_modules/mysql/lib/protocol/Protocol.js:291:23)
app_1    |     at Parser._parsePacket (/app/node_modules/mysql/lib/protocol/Parser.js:433:10)
app_1    |     at Parser.write (/app/node_modules/mysql/lib/protocol/Parser.js:43:10)
app_1    |     at Protocol.write (/app/node_modules/mysql/lib/protocol/Protocol.js:38:16)
app_1    |     at Socket.<anonymous> (/app/node_modules/mysql/lib/Connection.js:91:28)
app_1    |     at Socket.<anonymous> (/app/node_modules/mysql/lib/Connection.js:525:10)
app_1    |     at Socket.emit (events.js:310:20)
app_1    |     at addChunk (_stream_readable.js:286:12)
app_1    |     --------------------
app_1    |     at Protocol._enqueue (/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
app_1    |     at Protocol.handshake (/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
app_1    |     at PoolConnection.connect (/app/node_modules/mysql/lib/Connection.js:119:18)
app_1    |     at Pool.getConnection (/app/node_modules/mysql/lib/Pool.js:48:16)
app_1    |     at Pool.query (/app/node_modules/mysql/lib/Pool.js:202:8)
app_1    |     at /app/src/persistence/mysql.js:35:14
app_1    |     at new Promise (<anonymous>)
app_1    |     at Object.init (/app/src/persistence/mysql.js:34:12)
app_1    |     at processTicksAndRejections (internal/process/task_queues.js:97:5) {
app_1    |   code: 'ER_HOST_NOT_PRIVILEGED',
app_1    |   errno: 1130,
app_1    |   sqlMessage: "Host '172.26.0.2' is not allowed to connect to this MySQL server",
app_1    |   sqlState: undefined,
app_1    |   fatal: true
app_1    | }

如果我单独运行此命令来旋转MySQL,则会创建“ todos”数据库:

docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=todos mysql:5.7

在具有docker-compose的Windows上是否存在任何已更新的命令或无法正常运行的命令?

2 个答案:

答案 0 :(得分:10)

TL; DR;

运行命令

docker-compose down --volumes

要删除在教程早期阶段创建的任何有问题的卷,然后在步骤Running our Application Stack继续教程。


我想您所遵循的教程是this one

如果您确实一步一步地遵循它,并在步骤1或2中尝试了一些docker-compose up -d,那么您可能已经创建了volume,而没有todos数据库。

仅使用现有的 docker-compose.yml docker-compose down是不够的,因为为此专门创建了卷,该卷是Docker的永久存储层。

默认情况下,在容器内创建的所有文件都存储在可写容器层上。这意味着:

  • 当该容器不再存在时,数据将不会持久保存,并且如果另一个进程需要将数据从容器中取出可能会很困难。
  • 容器的可写层与运行容器的主机紧密耦合。您无法轻松地将数据移动到其他地方。
  • 写入容器的可写层需要存储驱动程序来管理文件系统。存储驱动程序使用Linux内核提供联合文件系统。与使用直接写入主机文件系统的数据卷相比,这种额外的抽象降低了性能。

Docker对于容器有两种选择,可以在主机中存储文件,这样即使容器停止后文件也可以持久保存:卷和绑定挂载。如果您在Linux上运行Docker,也可以使用tmpfs挂载。如果您在Windows上运行Docker,则还可以使用命名管道。

来源:https://docs.docker.com/storage/

为了删除该卷,您可能是在没有数据库的情况下创建的,可以向docker-compose down添加一个额外的标志:标志--volumes或简称为-v

-v, --volumes           Remove named volumes declared in the `volumes`
                            section of the Compose file and anonymous volumes
                            attached to containers.

来源:https://docs.docker.com/compose/reference/down/

因此,您的修复应该很简单:

  1. docker-compose down --volumes
  2. docker-compose up -d,因此请回到教程中的Running our Application Stack
  3. 按照本教程其余部分的提示
  4. docker-compose logs -f

答案 1 :(得分:0)

当前,当您启动docker-compose start时,您的数据库待办事项是在mysql容器内创建的。

实际上,您的问题来自mysql用户权限。

在文件末尾添加以下行以初始化待办事项数据库

  CREATE USER 'newuser'@'%' IDENTIFIED BY 'user_password';

该行将创建一个用户: newuser ,并使用密码 user_password

从任何主机(%)授予其访问权限

关注此行

GRANT ALL PRIVILEGES ON *.* TO 'newuser'@'%';

它将从任何主机

newuser 授予每个数据库和所有表的所有权限

最后,用刚创建的新变量更改mysql环境变量MYSQL_USER和MYSQL_PASSWORD

version: "3.7"

services:
  app:
    image: node:12-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: newuser
      MYSQL_PASSWORD: user_password
      MYSQL_DB: todos

  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data: