随着容器化技术的普及,Docker 已成为不少云原生应用开发和部署的首选平台。而其中一个常见的应用场景是容器与外部资源的交互,例如上传、下载文件等。但有时在使用 Docker 容器上传文件时,会发现文件流读取不到的情况。本文将探讨这种情况出现的原因,以及解决方法。
一、问题描述
我在使用 Docker 容器上传文件时,发现上传成功,但读取文件流时出现了问题,文件流为空。我尝试了多种方法,包括使用本地文件读取、远程文件读取,都无法解决。下面是我的代码示例:
import io from datetime import datetime from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/upload', methods=['POST']) def upload_file(): f = request.files['file'] stream = io.StringIO() stream.write(f.stream.read()) stream.seek(0) print(stream.read()) return jsonify({'success': True}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True)
使用 curl
命令上传文件时,可以看到上传成功了,但读取文件流时却为空:
$ curl -X POST -F "file=@test.txt" http://localhost:5000/upload {"success": true} $ python app.py 2019-12-26 16:10:10,990 - INFO - * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) 2019-12-26 16:10:16,930 - INFO -
二、问题分析
在容器内部,可以通过 docker cp
命令将文件复制到容器内部进行测试,可以发现文件流读取没有问题。所以问题显然不是出在读取文件流的代码上面。
我查阅了一些资料,发现 Docker 在处理上传文件时,会使用 TempFS 做为上传文件的临时存储目录。而可能出现的原因是,容器内部的文件系统隔离导致上传的文件不能被读取。
三、解决方法
解决该问题需要使用三种方法中的任意一种:
--privileged
运行容器启用特权模式,即使用 --privileged
运行容器。这个选项会让容器拥有主机的 root 权限。
$ docker run --privileged -d -p 5000:5000 my-image
--tmpfs /path/to/tmpfs:rw
选项使用 --tmpfs
挂载临时文件系统,可以保证上传的文件能够被正确地读取。
$ docker run -d -p 5000:5000 --tmpfs /tmp:rw my-image
直接将主机文件系统中的目录挂载到容器的某个路径下,可以使得容器内外都能够正确读取上传的文件。
$ docker run -d -p 5000:5000 -v /path/to/host/drive:/path/to/container/drive my-image
使用以上任一方法,再次上传测试,可以看到上传和读取文件流都成功了:
$ curl -X POST -F "file=@test.txt" http://localhost:5000/upload {"success": true} $ python app.py 2019-12-26 16:55:01,697 - INFO - * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) 2019-12-26 16:55:03,428 - INFO - This is a test file.
总之,Docker 的文件系统隔离机制有时会导致上传文件不能被正确读取,但有以上三种解决方法可以选择。希望本文能够对您在使用 Docker 应用程序时遇到的问题有所帮助。
以上是docker上传文件流读取不到怎么解决的详细内容。更多信息请关注PHP中文网其他相关文章!