【发布时间】:2022-02-11 01:15:41
【问题描述】:
我想使用 docker compose 将一个容器中的节点程序连接到另一个容器中的 MySQL 数据库。数据库似乎启动正常,但我的 index.js 文件抛出错误:Cannot find module 'mysql2/promise'
我试过用 npm 安装不同的包,甚至绝望地编辑了我的 package.json 文件中的各种行,但无济于事;总是同样的错误。以下是相关文件,以及目前有效的命令输出。
$ npm install mysql2
npm WARN simplyanything@1.0.0 No repository field.
npm WARN simplyanything@1.0.0 No license field.
+ mysql2@2.3.3
updated 1 package and audited 101 packages in 3.302s
found 0 vulnerabilities
$ sudo npm install mysql2-promise
+ mysql2-promise@0.1.4
updated 1 package and audited 101 packages in 3.772s
found 0 vulnerabilities
package.json
{
"name": "simplyanything",
"version": "1.0.0",
"scripts": {
"start": "node index.js"
},
"description": "Actions party game",
"dependencies": {
"express": "^4.17.1",
"mysql2": "^2.3.3",
"mysql2-promise": "^0.1.4",
"socket.io": "^4.4.1"
},
"author": "Chris DeHaan"
}
index.js
const express = require('express');
let app = express();
let http = require('http').createServer(app);
const io = require('socket.io')(http, {pingTimeout: 60000});
app.use(express.static('public'));
app.get('/', (req, res) => { res.sendFile(__dirname + '/index.html'); });
http.listen(3000, () => { console.log('listening on *:3000'); });
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
connectionLimit : 100,
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
[.... and so on]
Dockerfile
FROM node:latest
WORKDIR /sa/
COPY package.json .
RUN npm install
COPY . .
docker-compose.yml
version: '3.8'
services:
web:
build:
context: .
env_file: ./.env
command: npm start
volumes:
- .:/sa/
- /sa/node_modules
ports:
- $NODE_LOCAL_PORT:$NODE_DOCKER_PORT
depends_on:
- mysqldb
environment:
MYSQL_HOST: mysqldb
mysqldb:
image: mysql
env_file: ./.env
environment:
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
MYSQL_DATABASE: $MYSQL_DATABASE
ports:
- $MYSQL_LOCAL_PORT:$MYSQL_DOCKER_PORT
volumes:
- mysql:/var/lib/mysql
- mysql_config:/etc/mysql
volumes:
mysql:
mysql_config:
.env
MYSQL_USER=simplyanythingUser
MYSQL_ROOT_PASSWORD=[Well, you don't need to know this]
MYSQL_DATABASE=simplyanything
MYSQL_LOCAL_PORT=3306
MYSQL_DOCKER_PORT=3306
NODE_LOCAL_PORT=3000
NODE_DOCKER_PORT=3000
$ sudo docker build -t sa .
Sending build context to Docker daemon 9.526MB
Step 1/5 : FROM node:latest
---> e6bed6a65a54
Step 2/5 : WORKDIR /sa/
---> Using cache
---> 3da61e5a5928
Step 3/5 : COPY package.json .
---> Using cache
---> 1e7bbeaaa894
Step 4/5 : RUN npm install
---> Using cache
---> 52f36e54d698
Step 5/5 : COPY . .
---> e0a50567567b
Successfully built e0a50567567b
Successfully tagged sa:latest
$ node index.js
Debugger listening on ws://127.0.0.1:44273/a1b49bfc-83e7-47dd-ba53-64a8df19ccc9
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
listening on *:3000
(此时它可以在浏览器中运行)
$ sudo docker-compose up
Starting sa_mysqldb_1 ... done
Starting sa_web_1 ... done
Attaching to sa_mysqldb_1, sa_web_1
mysqldb_1 | 2022-02-08 08:31:21+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
mysqldb_1 | 2022-02-08 08:31:21+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
mysqldb_1 | 2022-02-08 08:31:21+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.28-1debian10 started.
mysqldb_1 | 2022-02-08T08:31:21.660916Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.28) starting as process 1
mysqldb_1 | 2022-02-08T08:31:21.747461Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
web_1 |
web_1 | > simplyanything@1.0.0 start
web_1 | > node index.js
web_1 |
mysqldb_1 | 2022-02-08T08:31:23.587278Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
web_1 | node:internal/modules/cjs/loader:936
web_1 | throw err;
web_1 | ^
web_1 |
web_1 | Error: Cannot find module 'mysql2/promise'
web_1 | Require stack:
web_1 | - /sa/index.js
web_1 | at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
web_1 | at Function.Module._load (node:internal/modules/cjs/loader:778:27)
web_1 | at Module.require (node:internal/modules/cjs/loader:999:19)
web_1 | at require (node:internal/modules/cjs/helpers:102:18)
web_1 | at Object.<anonymous> (/sa/index.js:13:15)
web_1 | at Module._compile (node:internal/modules/cjs/loader:1097:14)
web_1 | at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
web_1 | at Module.load (node:internal/modules/cjs/loader:975:32)
web_1 | at Function.Module._load (node:internal/modules/cjs/loader:822:12)
web_1 | at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) {
web_1 | code: 'MODULE_NOT_FOUND',
web_1 | requireStack: [ '/sa/index.js' ]
web_1 | }
web_1 |
web_1 | Node.js v17.4.0
mysqldb_1 | 2022-02-08T08:31:25.086275Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
mysqldb_1 | 2022-02-08T08:31:25.086445Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
mysqldb_1 | 2022-02-08T08:31:25.277625Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
mysqldb_1 | 2022-02-08T08:31:25.354311Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
mysqldb_1 | 2022-02-08T08:31:25.355558Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.28' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
我真的被卡住了,因为它所需的一切似乎都已安装,并且当我在命令行上使用 node index.js 运行它时它可以工作,所以显然在设置我的容器或编写时我缺少一些东西连接它们。任何建议将不胜感激。干杯。
【问题讨论】:
-
是的,这似乎是一个合理的尝试,但是将有问题的行更改为:
const mysql = require('mysql2-promise');会导致几乎相同的错误:Error: Cannot find module 'mysql2-promise'不过感谢您的评论。仅供参考,我的代码大量来自this page,这可能有助于澄清我哪里出错了?我觉得根本不需要mysql2-promise包,而mysql2/promise是不同的东西,包含在 mysql2 包中。 -
如果你使用 docker compose,你应该使用
docker compose build或docker compose up --build构建你的镜像 -
@Phil 完全正确的忽略文件,我现在有
.dockerignore正好一行,node_modules/在里面。谢谢你。至于构建命令,我假设你的意思是$ sudo docker-compose build,在这种情况下它运行成功,最后一行是Successfully tagged sa_web:latest。可悲的是,$ sudo docker-compose up然后以丢失模块的相同错误退出。 -
感谢@Phil 的持续支持。我从
Dockerfile中取出COPY . .,然后运行$ npm uninstall mysql2-promise。我的package.json在依赖项中不再有 mysql2-promises。这似乎是一种改进,更少的依赖。我对我的节点代码进行了一些更改以删除承诺,因此使用:mysql = require('mysql2');现在sudo docker-compose up之后的错误消息为:Error: Cannot find module 'mysql2'很明显,我对如何为容器提供模块的理解存在一个更根本的问题它需要。 -
好问题。是的,我确实重新构建了,第一次运行
$ sudo docker-compose build,我的第4步是这样的:步骤4/5:RUN npm install ---> 在4b3ec39e26cc中运行添加了85个包,并在9s 2个包中审核了86个包正在寻找资金运行npm fund以获取详细信息,发现 0 个漏洞,但现在如果我再做一次,它只会说:步骤 4/4 : RUN npm install ---> Using cache ---> 85c9f7f83401