Docker 容器中的 FTP 上传文件失败
Posted
技术标签:
【中文标题】Docker 容器中的 FTP 上传文件失败【英文标题】:FTP upload file failed in Docker container 【发布时间】:2020-06-26 15:56:33 【问题描述】:我有一个使用库 apache commons-net 的 Spring Boot 应用程序 我有一个在 AWS EC2 上运行的 FTP 服务器。 Filezilla正常连接上传文件。 本地应用正常连接和上传文件。 当我使用 Docker 运行这个应用程序时,应用程序连接到 ftp 成功,但它无法上传文件。 回复代码为:500Dockerfile:
FROM openjdk:11
RUN mkdir /app
COPY build/libs/aws-batch1-1.0.0.jar /app/aws-batch1.jar
ENTRYPOINT ["java","-jar","/app/aws-batch1.jar","Test"]
图像构建命令:
docker build -t aws-batch1 .
图像运行命令:
docker run aws-batch1
代码连接FTP:
private boolean connectFTPServer() throws IOException
LOGGER.info("CONNECT");
boolean flg = true;
try
ftpClient.connect(FTP_SERVER_ADDRESS, FTP_SERVER_PORT_NUMBER);
ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
catch (IOException e)
LOGGER.error("CONNECT FAILED", e);
flg = false;
int replyCode = ftpClient.getReplyCode();
LOGGER.info("replyCode: " + replyCode);
if (!FTPReply.isPositiveCompletion(replyCode))
flg = false;
if (!flg)
throw new IOException();
return flg;
代码上传文件:
public boolean uploadFile(byte[] content, String fileName)
throws IOException
boolean flg = false;
LOGGER.info("uploadFile");
if (connectFTPServer())
LOGGER.info("connectFTPServer success");
LOGGER.info("content: " + new String(content));
try (InputStream is = new ByteArrayInputStream(content))
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
boolean storeFile = ftpClient.storeFile(fileName, is);
LOGGER.info("storeFile: " + storeFile);
LOGGER.info("ftpClient.getReplyCode(): " + ftpClient.getReplyCode());
flg = storeFile &&
ftpClient.getReplyCode() ==
FTPReply.CLOSING_DATA_CONNECTION;
if (!flg)
throw new IOException("FTP error");
finally
closeConnectionFTPClient();
return flg;
本地上传成功时记录:
uploadFile
CONNECT
replyCode: 230
connectFTPServer success
content: test
storeFile: true
ftpClient.getReplyCode(): 226
在 Docker 上上传失败时记录:
uploadFile
CONNECT
replyCode: 230
connectFTPServer success
content: test
storeFile: false
ftpClient.getReplyCode(): 500
请帮助我。我是否缺少任何步骤?
更新:谢谢@Metin 我已更新代码以连接到 ftp 客户端,如下所示:
private boolean connectFTPServer() throws IOException
LOGGER.info("CONNECT");
boolean flg = true;
try
ftpClient.connect(FTP_SERVER_ADDRESS, FTP_SERVER_PORT_NUMBER);
ftpClient.login(FTP_USERNAME, FTP_PASSWORD);
ftpClient.enterLocalPassiveMode();
catch (IOException e)
LOGGER.error("CONNECT FAILED", e);
flg = false;
int replyCode = ftpClient.getReplyCode();
LOGGER.info("replyCode: " + replyCode);
if (!FTPReply.isPositiveCompletion(replyCode))
flg = false;
if (!flg)
throw new IOException();
return flg;
它有效!
【问题讨论】:
【参考方案1】:您可能想了解主动和被动模式 ftp 的区别:What is the difference between active and passive FTP?
您应该得出这样的结论,即主动模式 ftp 不适合容器化的 ftp 客户端,因为服务器主动尝试启动与 ftp 客户端的数据连接,这对于容器来说是不可能的(除非容器使用 network: host,这通常是不需要的)。
另一方面,使用被动模式 ftp,服务器会告诉您的 ftp 客户端需要使用哪个端口进行下一次数据连接。
【讨论】:
以上是关于Docker 容器中的 FTP 上传文件失败的主要内容,如果未能解决你的问题,请参考以下文章
docker容器中的django + nginx:无法上传任何带有表单的文件