我正在尝试容器化ftp服务器NodeJS应用程序。当我用npm运行它时,它工作得很好,但当我在容器内运行它时它没有响应。
这是节点应用程序: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运行服务器时,启动并使用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
为什么我的应用程序在节点中运行时可以工作,而在容器化时却不能工作?
侦听容器中的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客户端处于活动模式时,FTP服务器从客户端接收PORT
命令,并为该PORT
上的数据创建从容器返回到客户端的新TCP连接。
由于Docker端口映射到容器中,此数据连接的源地址通常与FTP客户端用作FTP服务器初始目的地的地址不匹配。在经典服务器上的NAT后面设置FTP服务器时也会出现类似的问题。
尝试绑定到0.0.0.0
。当您在Docker内部运行时,绑定127.0.0.1
将不起作用,因为请求将来自外部(至少从Docker容器的角度来看(。
有关解决此类网络问题的提示,您可以在这个相关问题的答案中找到一些想法。