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:无法上传任何带有表单的文件

FileZilla FTP上传大一点的文件失败

上传本地项目到docker运行的gitlab容器中

ftp上传文件失败,长传文件大小为零字节!

FTP 上传文件手动工作,但使用 Python ftplib 失败

ftp上传文件不能上传到指定的文件夹