【问题标题】:I get port in use error when I try to run the docker container for the nodejs and mysql application using the docker-compose当我尝试使用 docker-compose 为 nodejs 和 mysql 应用程序运行 docker 容器时出现端口使用错误
【发布时间】:2020-02-19 22:14:21
【问题描述】:

如何在启动时使用docker-compose 创建容器并将参数传递给我的 Node.js 应用程序?

我正在尝试编写一个程序,我可以在其中使用 NODEJS 和 DOCKER-COMPOSE 连接 MYSQL。我需要在终端中运行应用程序,以便我可以在启动期间将一些参数传递给我的 Node.js 应用程序,因此我需要运行 DOCKER-COMPOSE UP 来启动应用程序和 MYSQL,然后我想运行应用程序使用另一个窗口中的 CLI。

这是web 文件夹中的index.js 文件,当我使用以下命令nodemon start New 运行时,它将接受用户的输入。

     //Make NodeJS to Listen to a particular Port in Localhost
const   port        =   9010; 
     app.listen(port, function(){
        // Start the server and read the parameter passed by User
        console.log("Node js is Running on : "+port);
        // Get process.stdin as the standard input object.
        var standard_input = process.stdin;

        // Set input character encoding.
        standard_input.setEncoding('utf-8');

        // Prompt user to input data in console.
        console.log("Please input text in command line.");

        // When user input data and click enter key.
        standard_input.on('data', function (data) {
            console.log(" DATA ENTERED BY USER IS :"+data);
        });
    });

我想使用docker-compose 来实现这一点,因此我有docker-compose.yml 文件的以下代码。

version: '3'

services:
  db:
    build: ./db
    environment:
      MYSQL_DATABASE: mydb
      MYSQL_ROOT_PASSWORD: mypass
      MYSQL_USER: mysql
      MYSQL_PASSWORD: mypass
      DATABASE_HOST: myhost
  web:
    build: ./web
    depends_on:
      - db
    restart: on-failure
    ports:
      - "9010:9010"

  adminer:
    image: adminer
    restart: always
    ports:
      - "7778:8080"

web 文件夹中用于 web 或 Node.js 的 Dockerfile 是:

FROM node:8

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 9010

CMD ["npm","start"]

db 文件夹中数据库MYSQL 的Dockerfile 是:

FROM mysql:5.7

EXPOSE 3306

COPY ./scripts /docker-entrypoint-initdb.d/

现在,当我为 docker-compose.yml 文件运行命令 docker-compose up --build 时,一切正常;容器和 Node.js 应用程序启动。

当我打开另一个终端窗口并尝试使用docker-compose exec web sh 导航到web 容器并启动节点应用程序以传递参数nodemon start New 时,我收到以下错误。

events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRINUSE :::9010
    at Server.setupListenHandle [as _listen2] (net.js:1360:14)

由于在我运行命令 docker-compose up --build 时 Nodejs 应用程序已经在运行,因此端口已经分配,​​所以我收到此错误,如何启动 Indey.js 应用程序并将参数传递给它?

我正在为应用程序使用 Ubuntu Os。

【问题讨论】:

  • 如你所说,当容器启动时,Node 应用程序已经在运行,那你为什么要通过docker exec 再次启动它呢? (是否需要更改 Dockerfile 中的 CMD,或者在 Docker Compose YAML 文件中添加备用 command:?)
  • 但是对于那个 Node.js 应用程序,我无法传递参数,因为它已经启动,所以我只想创建容器。然后在另一个终端中,我想执行该容器,以便我可以在交互模式下运行 Node.js 应用程序并将参数传递给它。

标签: mysql node.js docker docker-compose port


【解决方案1】:

原因是已经有 nodejs 应用程序从CMD 运行并占用了端口,所以当在 docker 内运行命令时,你会得到EDDRINUSE 错误。

你会有多种选择,

  • 不要从 docker 的 CMD 启动 node 应用程序,但你不会注意到 nodejs 何时在容器内处理。 但这可以是处理的选项,所以在节点 Dockerfile 中更改 CMD
CMD ["npm","start"]
#change the above cmd to
CMD tail -f /dev/null

这只会让你的 nodejs 容器保持运行,然后在容器内运行命令。

docker-compose exec web sh
nodemon start New
  • 更改您手动运行的脚本的端口,这样就不会发生冲突,因为脚本将在不同的端口上启动,

稍微更新一下nodejs代码

//Make NodeJS to Listen to a particular Port in Localhost
const   port        =   process.env.PORT; 

现在用不同的端口启动进程

PORT=9011 nodemon start New

【讨论】:

  • 我还有一个小疑问。现在我首先运行命令docker-compose exec web sh,然后在Bash 中运行第二个命令PORT=9011 nodemon start New,是否可以将它结合起来并在单个命令中运行,因为它对最终用户来说很容易?我该怎么做?
  • 你可以试试这个或者docker-compose exec web sh -c "PORT=9011 nodemon start New"或者docker exec -it conainer_id sh -c "PORT=9011 nodemon start New"
  • 我还有一个问题,是否可以在不传递 PORT 号的情况下运行?我可以在 NODE.JS 中硬编码 PORT 号并使用它来运行它吗?如果是这样,那么我该如何避免端口冲突,这是我遇到的主要问题。
  • 您可以设置一些默认值,例如默认情况下它将针对9001 运行类似const port = process.env.PORT || 9000; 并覆盖传递端口到您的脚本
猜你喜欢
  • 2022-08-16
  • 2021-10-10
  • 1970-01-01
  • 2017-10-15
  • 2020-10-18
  • 2021-12-28
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
相关资源
最近更新 更多