node.js - 容器化时 NodeJS 应用程序停止工作 [容器中的 FTP 服务器]

标签 node.js docker dockerfile

我正在尝试将 ftp 服务器 NodeJS 应用程序容器化。当我使用 npm 运行它时它工作正常,但当我在容器内运行它时它没有响应。

这是 Node 应用程序: src/index.js 文件

const FtpSvr = require ( 'ftp-srv' );

const hostname = '127.0.0.1';
const port = 21;

const ftpServer = new FtpSvr ({
url:`ftp://${hostname}:${port}`,
anonymous:true
} );

ftpServer.on('login', ({connection, username, password}, resolve, reject) =>
{
    resolve({root : "./"})

    connection.on('STOR', (error, fileName) => {
        console.log("STOR")
    });
});

ftpServer.on ( 'client-error', (connection, context, error) =>
{
    console.log ( `error: ${error}` );
});

ftpServer.listen().then(() => {console.log(`Server running at http://${hostname}:${port}/`);});

我的 package.json 文件

{
  "name": "ftp-server",
  "version": "1.0.0",
  "description": "FTP server to receive images from cameras and save them on Azure Blob storage",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node src/index.js"
  },
  "author": "Rakshak",
  "license": "ISC",
  "dependencies": {
    "ftp-srv": "4.3.4"
  }
}

我的 docker 文件

FROM node:12

WORKDIR /app

COPY package.json ./

RUN npm install

COPY . .

EXPOSE 20-21
EXPOSE 65500-65515

CMD ["npm", "start"]

我正在使用 FileZilla 测试 FTP 服务器。当我使用 npm start 运行服务器并使用 FileZilla 连接时

Connecting to 127.0.0.1:5000...
Status:         Connection established, waiting for welcome message...
Status:         Insecure server, it does not support FTP over TLS.
Status:         Logged in
Status:         Retrieving directory listing...
Status:         Directory listing of "/" successful

我正在使用这个命令来构建 docker 镜像

 docker build -t rrakshak/ftp-demo .

我用它来运行 docker

 docker run -p 5000:5000 rrakshak/ftp-demo:latest

这是 FileZilla 控制台上的消息

Connecting to 127.0.0.1:5000...
Status:         Connection established, waiting for welcome message...
Error:          Connection closed by server
Error:          Could not connect to server
Status:         Waiting to retry...
Status:         Connecting to 127.0.0.1:5000...
Status:         Connection established, waiting for welcome message...
Error:          Connection closed by server
Error:          Could not connect to server

看起来当服务器在容器内运行时,FileZilla 能够连接但没有收到它期望的文件列表响应。

------------更新------------------------

将主机设置为 0.0.0。在 Filezilla 上给我一组新消息

Status:         Connecting to 127.0.0.1:21...
Status:         Connection established, waiting for welcome message...
Status:         Insecure server, it does not support FTP over TLS.
Status:         Logged in
Status:         Retrieving directory listing...
Command:    PWD
Response:   257 "/"
Command:    TYPE I
Response:   200 Switch to "binary" transfer mode.
Command:    PASV
Response:   502 Command not supported
Command:    PORT 127,0,0,1,231,209
Response:   500 The given address is not yours
Error:          Failed to retrieve directory listing

为什么我的应用程序在 Node 中运行时可以运行,但在容器化时却不能运行?

最佳答案

在容器中监听 0.0.0.0:5000,定义了被动端口

const FtpSvr = require ( 'ftp-srv' );
  
const hostname = '0.0.0.0';
const port = 5000;

const ftpServer = new FtpSvr ({
  url: `ftp://${hostname}:${port}`,
  anonymous: true,
  pasv_url: `ftp://${hostname}:${port}`,
  pasv_min: 65500,
  pasv_max: 65515,
});

按原样构建容器,然后使用映射的以下端口运行,这些端口都可以在 ftp 连接中使用:

docker run -p 5000:5000 -p 65500-65515:65500-65515 --rm rrakshak/ftp-demo

给出响应:

$ curl ftp://localhost:5000
-rw-r--r-- 1 1 1          141 Oct 21 01:22 Dockerfile
drwxr-xr-x 1 1 1         4096 Oct 21 01:21 node_modules
-rw-r--r-- 1 1 1        21137 Oct 21 01:21 package-lock.json
-rw-r--r-- 1 1 1           52 Oct 21 01:21 package.json
-rw-r--r-- 1 1 1          660 Oct 21 01:23 server.js
-rw-r--r-- 1 1 1        20287 Oct 21 01:21 yarn.lock

ftp 客户端必须设置为使用被动模式。

当 FTP 客户端位于 active mode 时,FTP 服务器接收到来自客户端的 PORT 命令,并创建一个从容器返回到客户端的新 TCP 连接,以获取该 PORT 上的数据。

由于 Docker 端口映射到容器中,此数据连接的源地址通常与 FTP 客户端用作 FTP 服务器初始目标的地址不匹配。在经典服务器上的 NAT 后面设置 FTP 服务器时会出现类似问题。

关于node.js - 容器化时 NodeJS 应用程序停止工作 [容器中的 FTP 服务器],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64438942/

相关文章:

javascript - 在新的 Promise() 构造函数中使用 async/await 是一种反模式吗?

docker - 需要帮助使用虚拟机配置重新镜像 Azure 批处理池中的现有 Azure 节点

Javascript:如何在没有 jQuery 或 AJAX 的情况下将 JSON 对象作为文件加载?

javascript - 在 Nodejs/Express 中链接 promise 的最佳实践

c# - VSTS 无法构建 docker 镜像

docker - Docker未导出环境变量

docker - Docker基于if-else设置ENV

python - 在 Dockerfile 中激活 python virtualenv

javascript - 在 Node.js 中处理滴答(或堆栈)之间的异常的策略?

node.js - Node.js https 的 SSL 握手失败