我正在从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上是否存在任何已更新的命令或无法正常运行的命令?
答案 0 :(得分:10)
运行命令
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/
因此,您的修复应该很简单:
docker-compose down --volumes
docker-compose up -d
,因此请回到教程中的Running our Application Stack 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: